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