次の方法で共有


Xamarin.Forms での動的スタイル

スタイルはプロパティの変更に応答しません。アプリケーションの期間中は変更されないままです。 たとえば、スタイルをビジュアル要素に割り当てた後、Setter インスタンスのいずれかが変更された、削除された、または新しい Setter インスタンスが追加された場合、変更はビジュアル要素に適用されません。 ただし、アプリケーションは、動的リソースを使って実行時にスタイルの変更に動的に応答できます。

DynamicResource マークアップ拡張と StaticResource マークアップ拡張は、両方ともディクショナリ キーを使用して ResourceDictionary から値を取得するという点で、似ています。 ただし、StaticResource が 1 回だけディクショナリ検索を実行するのに対して、DynamicResource はディクショナリ キーへのリンクを保持します。 そのため、キーに関連付けられているディクショナリ エントリが置き換えられると、その変更がビジュアル要素に適用されます。 これにより、実行時のスタイルの変更をアプリケーションで行うことができます。

次のコード例は、XAML ページの "動的" スタイルを示しています。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesPage" Title="Dynamic" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle"
                   TargetType="SearchBar"
                   BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle"
                   TargetType="SearchBar">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Placeholder="These SearchBar controls"
                       Style="{DynamicResource searchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SearchBar インスタンスは、DynamicResource マークアップ拡張機能を使って、XAML で定義されていない searchBarStyle という Style を参照します。 ただし、SearchBar インスタンスの Style プロパティは DynamicResource を使って設定されているため、ディクショナリ キーが欠落していても例外はスローされません。

代わりに、次のコード例に示すように、キー searchBarStyle を持つ ResourceDictionary エントリがコンストラクターによって分離コード ファイル内に作成されます。

public partial class DynamicStylesPage : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPage ()
    {
        InitializeComponent ();
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
    }

    void OnButtonClicked (object sender, EventArgs e)
    {
        if (originalStyle) {
            Resources ["searchBarStyle"] = Resources ["greenSearchBarStyle"];
            originalStyle = false;
        } else {
            Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];
            originalStyle = true;
        }
    }
}

OnButtonClicked イベント ハンドラーが実行されると、searchBarStyleblueSearchBarStylegreenSearchBarStyle の間で切り替わります。 これで、次のスクリーンショットのような結果になります。

青色の動的スタイルの例緑色の動的スタイルの例

次のコード例は、C# の同等のページを示しています。

public class DynamicStylesPageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesPageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        ...
        var searchBar1 = new SearchBar { Placeholder = "These SearchBar controls" };
        searchBar1.SetDynamicResource (VisualElement.StyleProperty, "searchBarStyle");
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = { searchBar1, searchBar2, searchBar3, searchBar4,    button    }
        };
    }
    ...
}

C# では、SearchBar インスタンスは SetDynamicResource メソッドを使って searchBarStyle を参照します。 OnButtonClicked イベント ハンドラー コードは XAML の例と同じであり、実行すると、searchBarStyleblueSearchBarStylegreenSearchBarStyle の間で切り替わります。

動的スタイルの継承

Style.BasedOn プロパティを使用して動的スタイルからスタイルを派生させることはできません。 代わりに、Style クラスには BaseResourceKey プロパティが含まれており、このプロパティを、値が動的に変更される可能性があるディクショナリ キーに設定できます。

次のコード例は、XAML ページの "動的" スタイルの継承を示しています。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Styles.DynamicStylesInheritancePage" Title="Dynamic Inheritance" IconImageSource="xaml.png">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="baseStyle" TargetType="View">
              ...
            </Style>
            <Style x:Key="blueSearchBarStyle" TargetType="SearchBar" BasedOn="{StaticResource baseStyle}">
              ...
            </Style>
            <Style x:Key="greenSearchBarStyle" TargetType="SearchBar">
              ...
            </Style>
            <Style x:Key="tealSearchBarStyle" TargetType="SearchBar" BaseResourceKey="searchBarStyle">
              ...
            </Style>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <SearchBar Text="These SearchBar controls" Style="{StaticResource tealSearchBarStyle}" />
            ...
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SearchBar インスタンスは、StaticResource マークアップ拡張機能を使って、tealSearchBarStyle という Style を参照します。 この Style は、いくつかの追加のプロパティを設定し、BaseResourceKey プロパティを使用して searchBarStyle を参照します。 DynamicResource マークアップ拡張は必要ありません。派生元の Style を除き、tealSearchBarStyle が変更されないからです。 そのため、tealSearchBarStylesearchBarStyle へのリンクを維持し、基本スタイルが変わると変更されます。

動的スタイルを示した前の例に従って、分離コード ファイルのコンストラクターでキー searchBarStyle を持つ ResourceDictionary エントリを作成します。 OnButtonClicked イベント ハンドラーが実行されると、searchBarStyleblueSearchBarStylegreenSearchBarStyle の間で切り替わります。 これで、次のスクリーンショットのような結果になります。

青色の動的スタイルの継承の例緑色の動的スタイルの継承の例

次のコード例は、C# の同等のページを示しています。

public class DynamicStylesInheritancePageCS : ContentPage
{
    bool originalStyle = true;

    public DynamicStylesInheritancePageCS ()
    {
        ...
        var baseStyle = new Style (typeof(View)) {
            ...
        };
        var blueSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var greenSearchBarStyle = new Style (typeof(SearchBar)) {
            ...
        };
        var tealSearchBarStyle = new Style (typeof(SearchBar)) {
            BaseResourceKey = "searchBarStyle",
            ...
        };
        ...
        Resources = new ResourceDictionary ();
        Resources.Add ("blueSearchBarStyle", blueSearchBarStyle);
        Resources.Add ("greenSearchBarStyle", greenSearchBarStyle);
        Resources ["searchBarStyle"] = Resources ["blueSearchBarStyle"];

        Content = new StackLayout {
            Children = {
                new SearchBar { Text = "These SearchBar controls", Style = tealSearchBarStyle },
                ...
            }
        };
    }
    ...
}

tealSearchBarStyle は、SearchBar インスタンスの Style プロパティに直接割り当てられます。 この Style でいくつかの追加プロパティを設定し、BaseResourceKey プロパティを使って searchBarStyle を参照します。 派生元の Style を除いて tealSearchBarStyle は変更されないため、ここでは SetDynamicResource メソッドは必要ありません。 そのため、tealSearchBarStylesearchBarStyle へのリンクを維持し、基本スタイルが変わると変更されます。

他の Xamarin ビデオは、Channel 9 および YouTube でご覧いただけます。