c# - XamlWriter.Save() 没有序列化 DependencyProperties

标签 c# wpf xaml xamlwriter uielementcollection

考虑我的 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 时,以下输出将写入控制台:

<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 内的元素执行此操作。

最佳答案

XamlWriter.Save 似乎只序列化本地-set 值。在 XAML 中,值可以来自 multiple levels of sources .

当您直接设置 TextBlock.Text 时,您正在查看“本地值”集(优先级 3)。但是,当您在数据模板中设置它时,您正在设置模板属性(优先级 4)。通过写作

textBlock.Text = textBlock.Text;

您实际上是在将其转换为本地属性集(优先级 3)!

如果您查看 some of the source code involved in XamlWriter.Save ,您可以看到 ( line 819 ) 它明确读取属性的本地值。

不幸的是,我不确定对此有什么好的解决方法。 XamlWriter 有 known limitations .你试试继承自 XamlDesignerSerializationManager并调用 XamlWriter.Save(Object, XamlDesignerSerializationManager)过载,但看起来不太有前途。更有可能的是,您将不得不执行上述操作,或者编写您自己的序列化例程(至少 Microsoft 已将其源代码作为指南随时提供)。

关于c# - XamlWriter.Save() 没有序列化 DependencyProperties,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28079024/

相关文章:

c# - ELMAH:仅通过邮件发送特定的异常类型

c# - 无法将控件添加到用户控件

c# - 如何在 wpf 中使用 Prism 打开新的模态对话框

c# - 如何在 WPF 中绑定(bind) Observable 集合的总和

c# - 在复选框列表中为选中的特定项目添加文本框 WPF

c# - 万事达卡的正则表达式

c# - 使用游标从使用 C# 的 SQL Server 读取时间序列数据?

wpf - 在 XAML 中使用图像向按钮添加鼠标悬停效果

c# - 将 BitmapImage 转换为 Image.Source

c# - UpdateSourceTrigger 未应用于样式化控件