【发布时间】:2015-01-21 23:48:45
【问题描述】:
考虑我的 UserControl 中的以下 XAML:
<TextBlock Text="HelloWorld" Loaded="TextBlock_OnLoaded" />
以及相关的事件处理程序:
private void TextBlock_OnLoaded(object sender, RoutedEventArgs e)
{
var xaml = XamlWriter.Save(sender);
Console.WriteLine(xaml);
}
加载 TextBlock 时,将以下输出写入控制台:
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
现在考虑这个替代 XAML:
<ListBox ItemsSource="{Binding SomeCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="HelloWorld" Loaded="TextBlock_OnLoaded" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
现在加载 TextBlock 时,以下输出将写入控制台:
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
......
请注意,TextProperty 不再被序列化。
如果在调用 XamlWriter.Save() 之前添加了以下 TextProperty 赋值:
private void TextBlock_OnLoaded(object sender, RoutedEventArgs e)
{
var textBlock = sender as TextBlock;
if (textBlock != null)
{
textBlock.Text = textBlock.Text;
}
var xaml = XamlWriter.Save(sender);
Console.WriteLine(xaml);
}
然后在加载TextBlock时,将以下输出写入Console:
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
......
请注意,TextProperty 再次被序列化。
这个blog post 解释说“...如果该属性由 DependencyProperty 支持...该属性仅在实际设置时才被写入。”
似乎在第一个用法示例中确实设置了 TextProperty,但在 ListBox 和 DataTemplate 的第二个用法示例中没有设置。
谁能解释为什么会这样,以及如何克服这个障碍?
我的最佳猜测是 XAML 解析器以某种方式在内部设置 TextBlock 状态,而不是在依赖属性上调用 SetValue,但我不确定为什么它只会对 DataTemplate 中的元素执行此操作。
【问题讨论】:
标签: c# wpf xaml xamlwriter uielementcollection