dotnet 9 WPF 支援 Style 的 Setter 填充內容時可忽略 Value 標籤

lindexi發表於2024-05-09

本文記錄 WPF 在 dotnet 9 的一項 XAML 編寫語法改進點,此改進點用於解決編寫 Style 的 Setter 進行給 Value 賦值時,不能將 Value 當成預設內容,需要多寫 Value 標籤的問題。透過此改進點可減少兩行 XAML 程式碼

在原先的 WPF 版本里面,對 Style 的 Setter 填充複雜的物件內容時,大概的示例程式碼如下

<Style TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                ...
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

可以看到 <Setter.Value> 屬於不可省略的內容

在本次引入的改進之後,即可將 Setter 的 Value 當成預設內容,從而減少 <Setter.Value> 的程式碼,改進後的寫法如下

<Style TargetType="Button">
    <Setter Property="Template">
        <ControlTemplate TargetType="Button">
            ...
        </ControlTemplate>
    </Setter>
</Style>

此改進是在許多年前,由 Thomas Levesque 大佬在 https://github.com/dotnet/wpf/issues/84 提出的。被微軟的 Anjalihttps://github.com/dotnet/wpf/pull/8534 實現

此變更將影響 XAML 語法,對應的文件也進行了同步更新,詳細請看 https://github.com/dotnet/dotnet-api-docs/pull/9581

為什麼之前的版本里面,必須編寫 <Setter.Value> 呢?這是因為在原先的版本里面 Style 的 Setter 的 Value 不是預設的內容,即在 Setter 標籤裡面直接放入內容,將不能被放入到 Value 屬性裡面

https://github.com/dotnet/wpf/pull/8534 的實現裡面,將 Setter 的 Value 當成預設內容,於是在 Setter 裡面放入的內容,將會自動給 Value 進行賦值

上述的核心邏輯在 src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/WpfGeneratedKnownTypes.cs 裡面,給建立 Setter 時,配置 baml 型別裡面內容對應的屬性名是 "Value" 屬性名,如以下程式碼

        private WpfKnownType Create_BamlType_Setter(bool isBamlType, bool useV3Rules)
        {
            var bamlType = new WpfKnownType(this, // SchemaContext
                                              556, "Setter",
                                              typeof(System.Windows.Setter),
                                              isBamlType, useV3Rules);
            bamlType.DefaultConstructor = delegate() { return new System.Windows.Setter(); };
            bamlType.ContentPropertyName = "Value"; // 這是本次更改的核心邏輯
            bamlType.Freeze();
            return bamlType;
        }

當前的 WPF 在 https://github.com/dotnet/wpf 完全開源,使用友好的 MIT 協議,意味著允許任何人任何組織和企業任意處置,包括使用,複製,修改,合併,發表,分發,再授權,或者銷售。在倉庫裡面包含了完全的構建邏輯,只需要本地的網路足夠好(因為需要下載一堆構建工具),即可進行本地構建

相關文章