1. 程式人生 > 其它 >UWP基礎教程 - XAML資源

UWP基礎教程 - XAML資源

在Windows 10 UWP應用開發中,XAML用於應用介面設計,無論是開發人員還是設計人員經常會設計自定義使用者介面或者控制元件行為,其中會涉及到不同方面的程式碼設計,例如控制元件模板控制元件樣式動畫設計等。為了方便設計,管理和重複利用這些通用程式碼,XAML提出了資源(Resources)的概念 資源(Resources),其概念和Web應用中的CSS(Cascading Style Sheets)樣式類似,其目的為了實現物件的重複呼叫。在Windows 10 UWP應用開發中,資源的概念不僅僅侷限於對控制元件樣式的定義,而且還包括對控制元件模板的定義,對字型的控制等。在實際專案中,開發人員可以在資源中設定多種不同控制元件屬性,在多個頁面呼叫通用資原始碼,這樣不僅有助於程式碼複用,也能夠提高應用維護的一致性。

我們來看一下定義一個資源的語法格式:

<根元素物件.Resources>
     <資源定義 />
</根元素物件.Resources>

在Windows 10 UWP應用開發中,每個Framework物件都支援Resources屬性,也就是說,可以在不同控制元件或者頁面定義特定的Resources, 在Page,Grid,Button定義Resources都是可以的。

XAML資源的概念在一定程度上簡化了XAML頁面程式碼,對於管理批量資原始碼集合,XAML還提供資源字典標記進行宣告。 在Windows 10 UWP應用開發中,所有能夠被定義在資源字典(ResourceDictionary)的物件必須是可被共享使用的。可以被應用於資源字典的物件如下:

  1. Style 和 Template
  2. Brushes 和 Colors
  3. Animation types (Storyboard)
  4. Transforms
  5. Matrix 和 Maxtrix3D
  6. Point
  7. Thickness 和 CornerRadius
  8. XAML intrinsic data types

在資源字典(ResourceDictionary)中,每一個資源項必須定義x:Key,也就是所謂的唯一標識的資源名稱,這樣可以方便讀取訪問。例如以下程式碼,在Page.Resources中定義資源x:Key = “bg”, 我們可以在Button中呼叫資源x:Key,應用資源到控制元件。

<Page>
    <Page.Resources>
            <LinearGradientBrush x:Key="bg" StartPoint="0.5,0" EndPoint="0.5,1">
                <GradientStop Color="Yellow" Offset="0.0" />
                <GradientStop Color="Blue" Offset="0.5" />
                <GradientStop Color="Green" Offset="1.0" />
            </LinearGradientBrush>
    </Page.Resources>
    <Button Background = "{StaticResource bg}"/>
</Page>

所有的XAML程式碼都可以轉化為C#程式碼的,那麼我們來看看上面XAML的C#實現。

ResourceDictionary dict = new ResourceDictionary();
LinearGradientBrush bgBrush = new LinearGradientBrush();
bgBrush.StartPoint = new Point(0.5,0);
bgBrush.EndPoint = new Point(0.5,1);
GradientStopCollection stops = new GradientStopCollection();
GradientStop stop1 = new GradientStop();
stop1.Color = Colors.Yellow;
            stop1.Offset = 0.0;
            stops.Add(stop1);
            GradientStop stop2 = new GradientStop();
stop2.Color = Colors.Blue;
            stop2.Offset = 0.5;
            stops.Add(stop2);
            GradientStop stop3 = new GradientStop();
stop3.Color = Colors.Green;
            stop3.Offset = 1.0;
            stops.Add(stop3);
            bgBrush.GradientStops = stops;
            dict.Add("bg", bgBrush);
this.LayoutRoot.Resources = dict;
this.btn.Background = (LinearGradientBrush)this.LayoutRoot.Resources["bg"];

Resources分為兩類FrameworkElement.ResourcesApplication.Resources

  1. FrameworkElement.Resources是將資源物件應用於同一個物件樹的不同物件上,也可被稱為即時資源(Immediate Resources), 或者稱為頁面資源(Page Resources)。通常來說,FrameworkElement.Resources會被定義在XAML頁面根元素上。
  2. Application.Resources可以被認為是貫串整個應用級別的資源,資源被定義在Application.Resources中,相比 FrameworkElement.Resources而言,Application.Resources應用範圍較廣,其生命週期也比 FrameworkElement.Resources要長。通常來說Application.Resources是被定義在啟動就載入的全域性容器裡,例如App.xaml。

我們先來看下FrameworkElement.Resources的使用,如下在Page中定義Resources

<Page>
    <Page.Resources></Page.Resources>
</Page>

Application.Resources定義是在Application.Resources中,如下程式碼所示

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source = "Style/Common.xaml" />
        </ResourceDictionary.MergedDictionaries >
    </ResourceDictionary >
</Application.Resources >

為了方便呼叫外部資原始檔,資源字典(ResourceDictionary)提供了MergedDictionaries屬性。 通常來說,合併資源字典屬性會被定義在Application.Resources, 也就是在App.xaml檔案中。 在使用合併資源字典屬性時,需要注意資源的查詢順序,例如:

<Application.Resources>
    <ResourceDictionary>
      <SolidColorBrush Color="red" x:Key="muddyBrush"/>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="test1.xaml" />
        <ResourceDictionary Source="test2.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources> 
![image.png](./10)

在上面程式碼的ResourceDictionary.MergedDictionaries中定義多個外部資原始檔,其查詢資源順序是從下往上逆序查詢的。test1.xaml和test2.xaml。 如果在兩個資原始檔中存在相同x:key的資源,test2.xaml中的資源將被優先採用。

作為外部資源合併,應用本身定義的資源永遠具有較高的優先順序,也就是說,如果在本地資源定義中,出現與test1.xaml,test2.xaml同名的資源,本地資源都被會優先採用。

在UWP中,主題資源字典(ThemeDictionaries)是一個特殊的合併資源字典。

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
        <x:String x:Key="BackButtonGlyph"></x:String>
        <x:String x:Key="BackButtonSnappedGlyph"></x:String>
    </ResourceDictionary>

    <ResourceDictionary x:Key="HighContrast">
        <x:String x:Key="BackButtonGlyph"></x:String>
        <x:String x:Key="BackButtonSnappedGlyph"></x:String>
    </ResourceDictionary>
    <ResourceDictionary x:Key="GreenTheme">
        <SolidColorBrush x:Key="MyBackgroundBrush" Color="Green"></SolidColorBrush>
    </ResourceDictionary>

    <ResourceDictionary x:Key="BlackTheme">
        <SolidColorBrush x:Key="MyBackgroundBrush" Color="Black"></SolidColorBrush>
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

與MergedDictionaries屬性相比較,在使用ThemeDictionaries時,需要為每個資源定義一個x:Key.例如上面的程式碼中的Default, HighContrast,在不同的主題時會查詢不同主題的資源進行渲染。

關於UWP開發XAML的部分到此就告一段落了,有什麼問題歡迎留言討論。