中的動態樣式 Xamarin.Forms

Download Sample 下載範例

樣式不會回應屬性變更,而且在應用程式期間維持不變。 例如,將 Style 指派給可視化項目之後,如果其中一個 Setter 實例已修改、移除或新增新的 Setter 實例,則變更將不會套用至視覺效果元素。 不過,應用程式可以使用動態資源,在運行時間動態響應樣式變更。

標記 DynamicResource 延伸類似於 StaticResource 中的標記延伸,這兩者都使用字典索引鍵從 ResourceDictionary擷取值。 不過,雖然 StaticResource 會執行單一字典查閱,但 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使用標記延伸來參考 Style XAML 中未定義的具名 searchBarStyle。 不過,由於 Style 實例的屬性 SearchBar 是使用 DynamicResource來設定,所以遺漏的字典索引鍵不會擲回例外狀況。

相反地,在程式代碼後置檔案中,建構函式會 ResourceDictionary 建立具有 機碼 searchBarStyle的專案,如下列程式代碼範例所示:

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執行事件處理程式時,searchBarStyle會在和 greenSearchBarStyle之間blueSearchBarStyle切換。 這會導致下列螢幕擷取畫面中顯示的外觀:

Blue Dynamic Style ExampleGreen Dynamic Style Example

下列程式代碼範例示範 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 方法來參考 searchBarStyleOnButtonClicked事件處理程式程式代碼與 XAML 範例相同,而且在執行時,searchBarStyle會在和 greenSearchBarStyle之間blueSearchBarStyle切換。

動態樣式繼承

您無法使用 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使用標記延伸來參考Style具名 tealSearchBarStyle的 。 這會 Style 設定額外屬性,並使用 BaseResourceKey 屬性來參考 searchBarStyleDynamicResource不需要標記延伸,因為 tealSearchBarStyle 不會變更,除非Style它衍生自 。 因此,在基底樣式變更時, tealSearchBarStyle 會維護 和的連結 searchBarStyle

在程式代碼後置檔案中,建構函式會根據先前示範動態樣式的範例,使用 ResourceDictionary 索引鍵 searchBarStyle建立專案。 OnButtonClicked執行事件處理程式時,searchBarStyle會在和 greenSearchBarStyle之間blueSearchBarStyle切換。 這會導致下列螢幕擷取畫面中顯示的外觀:

Blue Dynamic Style Inheritance ExampleGreen Dynamic Style Inheritance Example

下列程式代碼範例示範 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 直接指派給 Style 實例的 SearchBar 屬性。 這會 Style 設定額外屬性,並使用 BaseResourceKey 屬性來參考 searchBarStyleSetDynamicResource這裡不需要方法,因為 tealSearchBarStyle 不會變更,但衍生自 的方法除外Style。 因此,在基底樣式變更時, tealSearchBarStyle 會維護 和的連結 searchBarStyle

Channel 9YouTube 上尋找更多 Xamarin 影片。