在 Xamarin 中建立自訂的 Resource Dictionary 檔案

  • 710
  • 0

介紹如何在 Xamarin 中建立自訂的 Resource Dictionary (資源字典) 檔案。

最近受到 James Tsai 的感召,開始著手小玩一下 Xamarin.Forms,記得在寫 WPF/UWP 的時候自己常常要自訂一些 Resource Dictionary 檔案,於是小小研究了一下在 Xamarin.Forms 中如何完成這樣的需求。

在 UWP 中我們要新增個 Resource Dictionary 檔案很容易,只要加入新增項目,選擇資源字典就可以了。

接著我們在 Dictionary1.xaml 中設計一個簡單的 Style

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2">
    <Style x:Key="myTextBlockStyle" TargetType="TextBlock" >
        <Setter Property="Foreground" Value="Red"/>
    </Style>
</ResourceDictionary>

接著我們可以在其他的 xaml code 中利用 ResourceDictionary.MergedDictionaries 引用這個 Resource Dictionary
 

<Page
    x:Class="App2.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App2"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources >
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Style="{StaticResource myTextBlockStyle}" Text="This is a book"/>
    </Grid>
</Page>

 

我本來以為 Xamarin.Forms 也是這樣搞的,但是,永遠都有但是,在 Cross-Platform 的範本裡面連 Resource Dictionary 的範本都沒有,我翻了翻 Xarmarin 的原廠文件,其中只提到了怎麼合併(Merge)、怎麼在 App.xaml 建立 Resources,卻都沒找到怎麼建立一個獨立的 Resource Dictionary 檔案,所以第一個步驟是想辦法生出一個 Resource Dictionary 的檔案(也許是我文件看得不夠認真)。

首先,利用 Cross-Platform 範本中既有的 Forms Xaml View 範本建立檔案,檔案名稱就隨便取個 『MyDictionary.Xaml』。

接著修改 MyDictionary.xaml,把 ContentView 改成 ResourceDictionary,以及將 ContentView.Content 標記移除。

<?xml version="1.0" encoding="UTF-8"?>
<ResourceDictionary
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="XApp3.MyDictionary"> 
    
</ResourceDictionary>

第二個步驟是要修改 MyDictionary.xaml.cs,將 MyDictionary Class 的父類別由 ContentView 改成 ResourceDictionary。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace XApp3
{
    public partial class MyDictionary : ResourceDictionary
    {
        public MyDictionary()
        {
            InitializeComponent();
        }
    }
}

然後我們就可以快樂地在 MyDictionary.xaml 中建立資源。

<?xml version="1.0" encoding="UTF-8"?>
<ResourceDictionary
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="XApp3.MyDictionary">
    <Style x:Key="myLabelStyle" TargetType="Label">
        <Setter Property="TextColor" Value="Red"/>
    </Style>
</ResourceDictionary>

接下來的步驟要在一個 Page 中使用這個 Resource Dictionary,所以建立一個 Forms Xaml Page。

修改 Page1.xaml,加入必要的 xaml namespace -- xmlns:local="clr-namespace:XApp3" ,建立這個 ContentPage 的 Resources 標記,並使用 MergedWith 將我們剛剛建立的 Resource Dictionary 合併進來。最後在 Label 上套用 MyDictionary 中建立的 Style。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XApp3.Page1"
             xmlns:local="clr-namespace:XApp3">
    <ContentPage.Resources >
        <ResourceDictionary MergedWith="local:MyDictionary"/>
    </ContentPage.Resources>
  <Label Text="This is a book" VerticalOptions="Center" HorizontalOptions="Center" 
         Style="{StaticResource myLabelStyle}"/>
</ContentPage>

 

整個過程就是這麼簡單,如果你想把 Resource Dictionary 帶著走,可以利用類別庫專案,將 Resource Dictionary 檔案建立在類別庫中,編譯完成的 DLL 就可以讓其他專案引用了。

註:Xamrin.Forms 的 Nuget 套件版本需更新到 2.3.2.127