建立 XAML 標記延伸
在開發人員層級,.NET 多平臺應用程式 UI (.NET MAUI) XAML 標記延伸是實作 或 IMarkupExtension<T> 介面的IMarkupExtension類別。 您也可以從 或 IMarkupExtension<T>衍生IMarkupExtension來定義自己的自訂 XAML 標記延伸。 如果標記延伸取得特定類型的值,請使用泛型形式。 這是 .NET MAUI 標記延伸的數個案例:
TypeExtension
來自IMarkupExtension<Type>
ArrayExtension
來自IMarkupExtension<Array>
DynamicResourceExtension
來自IMarkupExtension<DynamicResource>
BindingExtension
來自IMarkupExtension<BindingBase>
實作 或的所有類別IMarkupExtension都必須以 RequireServiceAttribute 或 IMarkupExtension<T> AcceptEmptyServiceProviderAttribute加上批注。 如需詳細資訊,請參閱 服務提供者。
這兩 IMarkupExtension 個介面只會定義一個方法,每個方法名為 ProvideValue
:
public interface IMarkupExtension
{
object ProvideValue(IServiceProvider serviceProvider);
}
public interface IMarkupExtension<out T> : IMarkupExtension
{
new T ProvideValue(IServiceProvider serviceProvider);
}
由於 IMarkupExtension<T> 衍生自 IMarkupExtension 並包含 new
上的 ProvideValue
關鍵詞,因此它包含這兩 ProvideValue
種方法。
XAML 標記延伸通常會定義參與傳回值的屬性,而 ProvideValue
方法具有類型的 IServiceProvider
單一自變數。 如需服務提供者的詳細資訊,請參閱 服務提供者。
建立標記延伸
下列 XAML 標記延伸示範如何建立您自己的標記延伸。 它可讓您使用色調、飽和度和亮度元件來建構 Color 值。 它會為色彩的四個元件定義四個屬性,包括初始化為 1 的 Alpha 元件。 類別衍生自 IMarkupExtension<Color>
,表示傳 Color 回值:
public class HslColorExtension : IMarkupExtension<Color>
{
public float H { get; set; }
public float S { get; set; }
public float L { get; set; }
public float A { get; set; } = 1.0f;
public Color ProvideValue(IServiceProvider serviceProvider)
{
return Color.FromHsla(H, S, L, A);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider);
}
}
[AcceptEmptyServiceProvider]
public class HslColorExtension : IMarkupExtension<Color>
{
public float H { get; set; }
public float S { get; set; }
public float L { get; set; }
public float A { get; set; } = 1.0f;
public Color ProvideValue(IServiceProvider serviceProvider)
{
return Color.FromHsla(H, S, L, A);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<Color>).ProvideValue(serviceProvider);
}
}
這個標記延伸會加上批 AcceptEmptyServiceProviderAttribute 註,因為它不會使用來自服務提供者的服務。 如需詳細資訊,請參閱 服務提供者。
因為衍生自 ,類別IMarkupExtension<T>必須包含兩ProvideValue
個方法,一個傳回 Color ,另一個傳回 ,另一個傳回 object
,但第二個方法可以呼叫第一個IMarkupExtension方法。
取用標記延伸
下列 XAML 示範各種方法,可用來叫 HslColorExtension
用 來指定 的色彩 BoxView:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MarkupExtensions"
x:Class="MarkupExtensions.HslColorDemoPage"
Title="HSL Color Demo">
<ContentPage.Resources>
<Style TargetType="BoxView">
<Setter Property="WidthRequest" Value="80" />
<Setter Property="HeightRequest" Value="80" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
</Style>
</ContentPage.Resources>
<StackLayout>
<BoxView>
<BoxView.Color>
<local:HslColorExtension H="0" S="1" L="0.5" A="1" />
</BoxView.Color>
</BoxView>
<BoxView>
<BoxView.Color>
<local:HslColor H="0.33" S="1" L="0.5" />
</BoxView.Color>
</BoxView>
<BoxView Color="{local:HslColorExtension H=0.67, S=1, L=0.5}" />
<BoxView Color="{local:HslColor H=0, S=0, L=0.5}" />
<BoxView Color="{local:HslColor A=0.5}" />
</StackLayout>
</ContentPage>
在此範例中,當 是 XML 標記時 HslColorExtension
,四個屬性會設定為屬性,但在大括弧之間出現時,四個屬性會以逗號分隔,不含引號。 、 S
和 L
預設H
值為 0,預設值A
為 1,因此如果您想要將這些屬性設定為預設值,則可以省略這些屬性。 最後一個範例顯示一個範例,其中亮度為0,這通常會產生黑色,但Alpha色板為0.5,因此它是半透明,而且在頁面的白色背景顯示灰色:
服務提供者
藉由使用 IServiceProvider
的 ProvideValue
自變數,XAML 標記延伸可以存取它們正在使用之 XAML 檔案的相關數據。 例如,服務 IProvideValueTarget
可讓您擷取套用標記延伸的物件相關數據:
IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
介面 IProvideValueTarget
會定義兩個屬性和 TargetObject
TargetProperty
。 在類別中 HslColorExtension
取得這項資訊時, TargetObject
是 BoxView 的 ,而且 TargetProperty
是 Color
的 BoxView屬性。 這是已設定 XAML 標記延伸的屬性。
實作 或的所有類別IMarkupExtension都必須以 RequireServiceAttribute 或 IMarkupExtension<T> AcceptEmptyServiceProviderAttribute標註:
針對方法中的每個
ProvideValue
用法serviceProvider.GetService(typeof(T))
,類別應該加上[RequireService(typeof(T))]
批注:[RequireService([typeof(IReferenceProvider), typeof(IProvideValueTarget)])] public class MyMarkupExtension : IMarkupExtension { public object ProvideValue(IServiceProvider serviceProvider) { ... var referenceProvider = serviceProvider.GetService<IReferenceProvider>(); var valueProvider = serviceProvider.GetService<IProvideValueTarget>() as IProvideParentValues ?? throw new ArgumentException("serviceProvider does not provide an IProvideValueTarget"); ... } }
如果標記延伸未使用來自服務提供者的任何服務,則類別應該以
[AcceptEmptyServiceProvider]
標註。
由於 XAML 編譯程式優化可產生更有效率的程式代碼,有助於減少應用程式大小並改善運行時間效能,因此需要這些批注。