本文記錄 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 提出的。被微軟的 Anjali 在 https://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 協議,意味著允許任何人任何組織和企業任意處置,包括使用,複製,修改,合併,發表,分發,再授權,或者銷售。在倉庫裡面包含了完全的構建邏輯,只需要本地的網路足夠好(因為需要下載一堆構建工具),即可進行本地構建