XAML in Xamarin.Forms 基礎篇 電子書

XAML in Xamarin.Forms 基礎篇 電子書
XAML in Xamarin.Forms 基礎篇 電子書

Xamarin.Forms 快速入門 電子書

Xamarin.Forms 快速入門 電子書
Xamarin.Forms 快速入門 電子書

2016/09/01

Xamarin XAML 資源字典的繼承說明

XAML 資源字典的繼承說明

在這份筆記,將會記錄下 XAML 資源字典內的資源項目,在不同 視覺項目 (Visual Element) 內的繼承與覆蓋議題。

參考專案

執行畫面

資源字典的繼承說明

全域資源 App.xaml

在這個專案中,使用了 App.xaml 定義了一個全域的樣式 StyleForLabel;其定義了 Label 的 Text, TextColor, FontSize, VerticalOptions, HorizontalOptions 的屬性預設值。

App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ElementTree.App">
  <Application.Resources>
    <ResourceDictionary>
      <Style x:Key="StyleForLabel" TargetType="Label">
        <Setter Property="Text" Value="App 資源字典" />
        <Setter Property="TextColor" Value="Blue" />
        <Setter Property="FontSize" Value="32" />
        <Setter Property="VerticalOptions" Value="Center" />
        <Setter Property="HorizontalOptions" Value="Center" />
      </Style>
    </ResourceDictionary>
  </Application.Resources>
</Application>

頁面中的相關資源字典定義

每個在 XAML 內的視覺項目 Visual Element 都可以定義資源字典,在同樣的資源字典內,其 x:Key 名稱是不能夠重複的;不過,在不同的視覺項目內的資源字典,卻可以定義同樣的資源名稱;另外,只要是在同一個視覺樹(Visual Tree)下,最上層定義的資源項目,是可以在底下階層的視覺項目直接來引用。
在這個頁面內,並沒有定義 ContentPage 的資源字典,並且所有的 Label 控制項,都使用同樣的 Style 靜態參考 StaticResource StyleForLabel; 而在第一個 Label 控制項中,將會採用全域資源中的資源項目。
第二個 Label 控制項目,將會使用上層 StackLayour 內資源字典定義的資源項目。
第三個 Label 控制項目,將會使用本身資源字典定義的資源項目。

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ElementTree"
             x:Class="ElementTree.MainPage">

  <StackLayout
    Orientation="Vertical"
    VerticalOptions="Center"
    >
    <Label Style="{StaticResource StyleForLabel}"/>
    <StackLayout
      Orientation="Vertical">
      <StackLayout.Resources>
        <ResourceDictionary>
          <Style x:Key="StyleForLabel" TargetType="Label">
            <Setter Property="Text" Value="StackLayour 資源字典" />
            <Setter Property="TextColor" Value="Red" />
            <Setter Property="FontSize" Value="18" />
            <Setter Property="VerticalOptions" Value="Center" />
            <Setter Property="HorizontalOptions" Value="Center" />
          </Style>
        </ResourceDictionary>
      </StackLayout.Resources>
      <Label Style="{StaticResource StyleForLabel}" />
      <Label Style="{StaticResource StyleForLabel}" >
        <Label.Resources>
          <ResourceDictionary>
            <Style x:Key="StyleForLabel" TargetType="Label">
              <Setter Property="Text" Value="Label 資源字典" />
              <Setter Property="TextColor" Value="Green" />
              <Setter Property="FontSize" Value="24" />
              <Setter Property="VerticalOptions" Value="Center" />
              <Setter Property="HorizontalOptions" Value="Center" />
            </Style>
          </ResourceDictionary>
        </Label.Resources>
      </Label>
    </StackLayout>
  </StackLayout>

</ContentPage>

2016/08/31

Xamarin XAML 靜態與動態資源的使用

XAML 靜態與動態資源的使用

在這份筆記,將會記錄下 XAML 樣式 Style 的各種應用,這包括了
  • 資源字典 Resource Dictionary 的使用
  • x:Static (取得公開靜態欄位值)
  • StaticResource (參考靜態樣式資源)
  • DynamicResource (參考動態樣式與資源)

參考專案

.NET 靜態屬性

這個專案內,定義了一個類別 PubStat,裡面有三個靜態屬性,將會在 XAML 內,使用 x:Static 來存取。

PubStat.cs

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

namespace DynaStat
{
    public class PubStat
    {
        public static Color 文字顏色 { get; set; } = Color.Red;
        public static Color 背景顏色 { get; set; } = Color.Yellow;
        public static double 文字尺寸 { get; set; } = 20;
    }
}

全域樣式 App.XAML

這個專案,定義了全域資源,定義了兩個顏色資源與一個 Double 資源。
而關於 Double 資源,您不能夠直接使用 .NET double 關鍵字,需要使用 XAML 標記延伸功能 x:Double

App.XAML

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DynaStat.App">
  <Application.Resources>

    <ResourceDictionary>
      <Color x:Key="GlobalbackgroundColor">#ccffcc</Color>
      <Color x:Key="GlobaltextColor">#ff6600</Color>
      <x:Double x:Key="GlobalfontSize">24</x:Double>
    </ResourceDictionary>
  </Application.Resources>
</Application>

啟動頁面 MainPage.xaml

在這個頁面,定義了 ContentPage.Resources 的資源字典,裡面定義了頁面內使用的三個資源。
若要在頁面內的控制項目 (Control Element)引用資源字典內的資源項目,可以使用 StaticResource 或者DynamicResource
當套用 StaticResource 的屬性,在整個應用程式執行時期,出現的樣式都是一樣的
當套用 DynamicResource 的屬性,只要在 code-behind 內有變更這個資源屬性值,當時套用這個動態資源的屬性,也會立即變更
若您要設定的控制項屬性值,是要參考 .NET 靜態屬性值,可以使用 x:Static 標記擴充功能,來參考 .NET 的靜態屬性值。不過,當您在 code-behind 內變更了這些 .NET 靜態屬性值,當時的頁面或者控制項是無法立即變更已經修正的屬性值,必須要重新建立一個新頁面之後,才會看到醉心繫結的 .NET 靜態屬性值。

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DynaStat"
             x:Class="DynaStat.MainPage">

  <ContentPage.Resources>
    <ResourceDictionary>
      <Color x:Key="backgroundColor">#ccffcc</Color>
      <Color x:Key="textColor">#ff6600</Color>
      <x:Double x:Key="fontSize">24</x:Double>
    </ResourceDictionary>
  </ContentPage.Resources>

  <StackLayout
    Orientation="Vertical"
    HorizontalOptions="Center"
    VerticalOptions="Center"
  >
    <Label Text="使用 StaticResource"
           VerticalOptions="Center"
           HorizontalOptions="Center"
           TextColor="{StaticResource textColor}"
           BackgroundColor="{StaticResource backgroundColor}"
           FontSize="{StaticResource fontSize}"
         />
    <Label Text="使用 DynamicResource"
           VerticalOptions="Center"
           HorizontalOptions="Center"
           TextColor="{DynamicResource textColor}"
           BackgroundColor="{DynamicResource backgroundColor}"
           FontSize="{DynamicResource fontSize}"
         />
    <Button x:Name="btnDynamic" Text="變更動態資源"/>
    <Label Text="使用全域 DynamicResource"
           VerticalOptions="Center"
           HorizontalOptions="Center"
           TextColor="{DynamicResource GlobaltextColor}"
           BackgroundColor="{DynamicResource GlobalbackgroundColor}"
           FontSize="{DynamicResource GlobalfontSize}"
         />
    <Button x:Name="btnGlobalDynamic" Text="變更全域動態資源"/>
    <Label Text="使用 公開靜態屬性"
           VerticalOptions="Center"
           HorizontalOptions="Center"
           TextColor="{x:Static local:PubStat.文字顏色}"
           BackgroundColor="{x:Static local:PubStat.背景顏色}"
           FontSize="{x:Static local:PubStat.文字尺寸}"
         />
    <Button x:Name="btnStatic" Text="變更公開靜態屬性"/>
    <Button x:Name="btnReset" Text="重新啟動該頁面"/>
  </StackLayout>

</ContentPage>

執行結果

以上說明可以從底下的執行操作更加清楚了解。
當應用程式執行的時候,會顯示如下畫面
您可以看到,不論使用靜態資源或者動態資源,所看到的樣貌都是一樣的。
靜態與動態資源
當按下了 變更動態資源 按鈕,會出現底下畫面
在這個按鈕處理事件內,使用頁面的 Resources 屬性值,修正了頁面內的動態資源內容,因此,頁面上立即會將有使用 DynamicResource 定義的屬性,反映出最新的內容。
            btnDynamic.Clicked += (s, e) =>
              {
                  this.Resources["backgroundColor"] = Color.White;
                  this.Resources["textColor"] = Color.Black;
                  this.Resources["fontSize"] = 30;
                  btnDynamic.Text = $"變更動態資源 " + this.Resources.Count.ToString();
              };
靜態與動態資源
當按下了 變更全域動態資源 按鈕,會出現底下畫面
在這個按鈕處理事件內,使用頁面的 App.Current.Resources 屬性,修正了整個應用程式全域的動態資源內容,因此,頁面上立即會將有使用 DynamicResource 定義的屬性,反映出最新的內容。
            btnGlobalDynamic.Clicked += (s, e) =>
              {
                  App.Current.Resources["GlobalbackgroundColor"] = Color.White;
                  App.Current.Resources["GlobaltextColor"] = Color.Black;
                  App.Current.Resources["GlobalfontSize"] = 30;
                  btnGlobalDynamic.Text = $"變更全域動態資源 "+ App.Current.Resources.Count.ToString();
              };
靜態與動態資源
不過,當您按下了按鈕 變更公開靜態屬性 按鈕,並且變更了 .NET 靜態屬性內容,會發現到頁面並沒有做出任何變化或者更新。
            btnStatic.Clicked += (s, e) =>
              {
                  PubStat.文字顏色 = Color.Blue;
                  PubStat.背景顏色 = Color.Pink;
                  PubStat.文字尺寸 = 30;
              };
靜態與動態資源
現在,請按下按鈕 重新啟動該頁面,使用這個 C# 敘述 App.Current.MainPage = new MainPage();,重新定義應用程式的起始頁面。
因為重新產生了一個新的 MainPage 物件執行個體,此時,在這個新產生的執行個體,使用了 x:Static 參考到的 .NET 靜態屬性,將會是剛剛變更後的內容,也就是會產生另外一個樣式結果。
            btnReset.Clicked += (s, e) =>
              {
                  App.Current.MainPage = new MainPage();
              };
靜態與動態資源