共用方式為


建立 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都必須以 RequireServiceAttributeIMarkupExtension<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 ,四個屬性會設定為屬性,但在大括弧之間出現時,四個屬性會以逗號分隔,不含引號。 、 SL 預設H值為 0,預設值A為 1,因此如果您想要將這些屬性設定為預設值,則可以省略這些屬性。 最後一個範例顯示一個範例,其中亮度為0,這通常會產生黑色,但Alpha色板為0.5,因此它是半透明,而且在頁面的白色背景顯示灰色:

HSL 色彩示範。

服務提供者

藉由使用 IServiceProviderProvideValue自變數,XAML 標記延伸可以存取它們正在使用之 XAML 檔案的相關數據。 例如,服務 IProvideValueTarget 可讓您擷取套用標記延伸的物件相關數據:

IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

介面 IProvideValueTarget 會定義兩個屬性和 TargetObject TargetProperty。 在類別中 HslColorExtension 取得這項資訊時, TargetObjectBoxView 的 ,而且 TargetPropertyColorBoxView屬性。 這是已設定 XAML 標記延伸的屬性。

實作 或的所有類別IMarkupExtension都必須以 RequireServiceAttributeIMarkupExtension<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 編譯程式優化可產生更有效率的程式代碼,有助於減少應用程式大小並改善運行時間效能,因此需要這些批注。