通路靜态成員
IMarkupExtension最簡單和最有用的實作之一封裝在StaticExtension類中。 這是原始XAML規範的一部分,是以它通常出現在帶有x字首的XAML中。 StaticExtension定義了一個名為Member of string的屬性,您可以将其設定為公共常量,靜态屬性,靜态字段或枚舉成員的類和成員名稱。
讓我們看看它是如何工作的。 這是一個标簽,其中六個屬性設定為通常在XAML中顯示的屬性:
<Label Text="Just some text"
BackgroundColor="Accent"
TextColor="Black"
FontAttributes="Italic"
VerticalOptions="Center"
HorizontalTextAlignment="Center" />
其中五個屬性設定為最終引用各種靜态屬性,字段和枚舉成員的文本字元串,但這些文本字元串的轉換通過類型轉換器和枚舉類型的标準XAML解析進行。
如果您希望更明确地将這些屬性設定為各種靜态屬性,字段和枚舉成員,則可以在屬性元素标記中使用x:StaticExtension:
<Label Text="Just some text">
<Label.BackgroundColor>
<x:StaticExtension Member="Color.Accent" />
</Label.BackgroundColor>
<Label.TextColor>
<x:StaticExtension Member="Color.Black" />
</Label.TextColor>
<Label.FontAttributes>
<x:StaticExtension Member="FontAttributes.Italic" />
</Label.FontAttributes>
<Label.VerticalOptions>
<x:StaticExtension Member="LayoutOptions.Center" />
</Label.VerticalOptions>
<Label.HorizontalTextAlignment>
<x:StaticExtension Member="TextAlignment.Center" />
</Label.HorizontalTextAlignment>
</Label>
Color.Accent是一個靜态屬性。 Color.Black和LayoutOptions.Center是靜态字段。 FontAttributes.Italic和TextAlignment.Center是枚舉成員。
考慮到使用文本字元串設定這些屬性的難易程度,使用Stat?icExtension的方法最初看起來很荒謬,但請注意它是一種通用機制。 如果StaticExtension标記的類型與target屬性的類型比對,則可以使用StaticExtension标記中的任何靜态屬性,字段或枚舉成員。
按照慣例,實作IMarkupExtension的類在其名稱中包含單詞Extension,但您可以将其保留在XAML中,這就是為什麼此标記擴充通常稱為x:Static而不是x:StaticExtension。 以下标記略微短于前一個塊:
<Label Text="Just some text">
<Label.BackgroundColor>
<x:Static Member="Color.Accent" />
</Label.BackgroundColor>
<Label.TextColor>
<x:Static Member="Color.Black" />
</Label.TextColor>
<Label.FontAttributes>
<x:Static Member="FontAttributes.Italic" />
</Label.FontAttributes>
<Label.VerticalOptions>
<x:Static Member="LayoutOptions.Center" />
</Label.VerticalOptions>
<Label.HorizontalTextAlignment>
<x:Static Member="TextAlignment.Center" />
</Label.HorizontalTextAlignment>
</Label>
現在,對于真正重大的主要 - 文法的改變導緻屬性元素标簽消失,占用空間大大縮小。 XAML标記擴充幾乎與标記擴充名和一對花括号中的參數一起出現:
<Label Text="Just some text"
BackgroundColor="{x:Static Member=Color.Accent}"
TextColor="{x:Static Member=Color.Black}"
FontAttributes="{x:Static Member=FontAttributes.Italic}"
VerticalOptions="{x:Static Member=LayoutOptions.Center}"
HorizontalTextAlignment="{x:Static Member=TextAlignment.Center}" />
這種帶有花括号的文法無處不在地與XAML标記擴充一起使用,許多開發人員認為标記擴充與大括号文法同義。 這幾乎是正确的:雖然花括号總是表示存在XAML标記擴充,但在許多情況下,标記擴充可以在沒有花括号的XAML中出現(如前所示),并且有時可以友善地使用它們。
staticExtension類的operty不再是XML屬性。 就XML而言,由花括号分隔的整個表達式是屬性的值,并且花括号内的參數不帶引号。
就像元素一樣,标記擴充可以具有ContentProperty屬性。 僅具有一個屬性的标記擴充(例如具有單個成員屬性的StaticExtension類)始終将該唯一屬性标記為内容屬性。 對于使用卷括号文法的标記擴充,這意味着可以删除成員屬性名稱和等号:
<Label Text="Just some text"
BackgroundColor="{x:Static Color.Accent}"
TextColor="{x:Static Color.Black}"
FontAttributes="{x:Static FontAttributes.Italic}"
VerticalOptions="{x:Static LayoutOptions.Center}"
HorizontalTextAlignment="{x:Static TextAlignment.Center}" />
這是x:Static标記擴充的常見形式。
顯然,不需要對這些特定屬性使用x:Static,但是您可以定義自己的靜态成員來實作應用程式範圍的常量,并且可以在XAML檔案中引用它們。 這在SharedStatics項目中得到了證明。
SharedStatics項目包含一個名為AppConstants的類,它定義了一些可能用于格式化文本的常量和靜态字段:
namespace SharedStatics
{
static class AppConstants
{
public static Color LightBackground = Color.Yellow;
public static Color DarkForeground = Color.Blue;
public static double NormalFontSize = 18;
public static double TitleFontSize = 1.4 * NormalFontSize;
public static double ParagraphSpacing = 10;
public const FontAttributes Emphasis = FontAttributes.Italic;
public const FontAttributes TitleAttribute = FontAttributes.Bold;
public const TextAlignment TitleAlignment = TextAlignment.Center;
}
}
如果每個平台需要不同的東西,可以在這些定義中使用Device.OnPlatform。
然後,XAML檔案使用18 x:靜态标記擴充來引用這些項。 請注意将本地字首與項目命名空間相關聯的XML名稱空間聲明:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SharedStatics"
x:Class="SharedStatics.SharedStaticsPage"
BackgroundColor="{x:Static local:AppConstants.LightBackground}">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<StackLayout Padding="10, 0"
Spacing="{x:Static local:AppConstants.ParagraphSpacing}">
<Label Text="The SharedStatics Program"
TextColor="{x:Static local:AppConstants.DarkForeground}"
FontSize="{x:Static local:AppConstants.TitleFontSize}"
FontAttributes="{x:Static local:AppConstants.TitleAttribute}"
HorizontalTextAlignment="{x:Static local:AppConstants.TitleAlignment}" />
<Label TextColor="{x:Static local:AppConstants.DarkForeground}"
FontSize="{x:Static local:AppConstants.NormalFontSize}">
<Label.FormattedText>
<FormattedString>
<Span Text="Through use of the " />
<Span Text="x:Static"
FontSize="{x:Static local:AppConstants.NormalFontSize}"
FontAttributes="{x:Static local:AppConstants.Emphasis}" />
<Span Text=
" XAML markup extension, an application can maintain a collection of
common property settings defined as constants, static properties or fields,
or enumeration members in a separate code file. These can then be
referenced within the XAML file." />
</FormattedString>
</Label.FormattedText>
</Label>
<Label TextColor="{x:Static local:AppConstants.DarkForeground}"
FontSize="{x:Static local:AppConstants.NormalFontSize}">
<Label.FormattedText>
<FormattedString>
<Span Text=
"However, this is not the only technique to share property settings.
You'll soon discover that you can store objects in a " />
<Span Text="ResourceDictionary"
FontSize="{x:Static local:AppConstants.NormalFontSize}"
FontAttributes="{x:Static local:AppConstants.Emphasis}" />
<Span Text=" and access them through the " />
<Span Text="StaticResource"
FontSize="{x:Static local:AppConstants.NormalFontSize}"
FontAttributes="{x:Static local:AppConstants.Emphasis}" />
<Span Text=
" markup extension, and even encapsultate multiple property settings in a " />
<Span Text="Style"
FontSize="{x:Static local:AppConstants.NormalFontSize}"
FontAttributes="{x:Static local:AppConstants.Emphasis}" />
<Span Text=" object." />
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
</ContentPage>
具有FontAttributes設定的每個Span對象都會重複在Label本身上設定的FontSize設定,因為當應用其他與字型相關的設定時,Span對象不會從Label繼承與字型相關的設定。
這是:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicWZwpmLkFGZwEDM5UDO4YDOzE2MzUjY1EGN0YmMmljN1EjNwcTNyYGN0MDMy8CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpeg)
此技術允許您在多個頁面上使用這些公共屬性設定,如果您需要更改值,則隻需更改AppSettings檔案。
也可以使用x:Static和靜态屬性以及在外部li?braries中的類中定義的字段。 下面的示例名為SystemStatics,它設計得非常合适 - 它将Button的BorderWidth設定為等于Math類中定義的PI靜态字段,并使用靜态Environment.New?Line屬性來處理文本中的換行符。 但它證明了這項技術。
Math和Environment類都在.NET System命名空間中定義,是以需要新的XML命名空間聲明來定義名為(例如)sys for System的字首。 請注意,此命名空間聲明将CLR命名空間指定為System,但将程式集指定為mscorlib,它最初代表Microsoft公共對象運作時庫,但現在代表多語言标準公共對象運作時庫:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="SystemStatics.SystemStaticsPage">
<StackLayout>
<Button Text=" Button with π border width "
BorderWidth="{x:Static sys:Math.PI}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<Button.BackgroundColor>
<OnPlatform x:TypeArguments="Color"
Android="#404040" />
</Button.BackgroundColor>
<Button.BorderColor>
<OnPlatform x:TypeArguments="Color"
Android="White"
WinPhone="Black" />
</Button.BorderColor>
</Button>
<Label VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"
FontSize="Medium">
<Label.FormattedText>
<FormattedString>
<Span Text="Three lines of text" />
<Span Text="{x:Static sys:Environment.NewLine}" />
<Span Text="separated by" />
<Span Text="{x:Static sys:Environment.NewLine}" />
<Span Text="Environment.NewLine"
FontSize="Medium"
FontAttributes="Italic" />
<Span Text=" strings" />
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
</ContentPage>
除非設定了背景顔色,否則按鈕邊框不會顯示在Android中,并且在An?droid和Windows Phone上邊框都需要非預設顔色,是以一些額外的标記可以解決這些問題。 在iOS平台上,按鈕邊框往往會擠壓按鈕文本,是以文本在開頭和結尾都定義了空格。
僅從視覺效果來判斷,我們必須相信按鈕邊框寬度約為3.14機關寬,但斷線肯定有效:
使用花括号進行标記擴充意味着您無法顯示由花括号括起來的文本。 本文中的花括号将被誤認為是标記擴充名:
<Label Text="{Text in curly braces}" />
那不行。 您可以在文本字元串中的其他位置使用花括号,但不能以左大括号開頭。
但是,如果确實需要,可以通過使用由左右一對花括号組成的轉義序列開始文本,確定文本不會被誤認為是XAML标記擴充:
<Label Text="{}{Text in curly braces}" />
這将顯示您想要的文本。