C# XamlWriter.Save()未序列化DependencyProperties
考虑来自my UserControl的以下XAML:C# XamlWriter.Save()未序列化DependencyProperties,c#,wpf,xaml,xamlwriter,uielementcollection,C#,Wpf,Xaml,Xamlwriter,Uielementcollection,考虑来自my UserControl的以下XAML: <TextBlock Text="HelloWorld" Loaded="TextBlock_OnLoaded" /> 加载TextBlock时,将以下输出写入控制台: <TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation
<TextBlock Text="HelloWorld" Loaded="TextBlock_OnLoaded" />
加载TextBlock时,将以下输出写入控制台:
<TextBlock Text="HelloWorld" 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" />
<TextBlock 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" />
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
......
然后,当加载TextBlock时,将以下输出写入控制台:
<TextBlock Text="HelloWorld" 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" />
<TextBlock 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" />
<TextBlock Text="HelloWorld" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
......
......
请注意,TextProperty再次被序列化
这解释了“…如果属性由DependencyProperty支持…则仅在实际设置属性时才写入该属性。”
在第一个使用示例中,似乎确实设置了TextProperty,但在第二个使用示例中,ListBox和DataTemplate没有设置TextProperty
有人能解释为什么会这样,以及如何克服这个障碍吗
我最好的猜测是,XAML解析器以某种方式在内部设置TextBlock状态,而不是在dependency属性上调用SetValue,但我不确定为什么它只对DataTemplate内的元素执行此操作。
XamlWriter.Save
似乎只在本地序列化设置值。在XAML中,值可以来自
当您直接设置TextBlock.Text时,您看到的是一个“本地值”集(优先级3)。但是,当您在数据模板内设置它时,您正在设置模板属性(优先级4)。通过写作
textBlock.Text = textBlock.Text;
实际上,您正在将其转换为本地属性集(优先级3)
如果查看()可以看到它显式读取属性的本地值
不幸的是,我不确定这是一个好的解决办法。XamlWriter有。您可以尝试继承并调用重载,但它看起来不太有希望。更可能的情况是,您必须执行上述操作,或者编写自己的序列化例程(至少Microsoft已经提供了其源代码作为指南)。根据的回答,我提出了以下解决方法:
public static IEnumerable<DependencyProperty> GetDependencyProperties(this DependencyObject obj)
{
var propertyDescriptors = TypeDescriptor.GetProperties(obj, new Attribute[]
{
new PropertyFilterAttribute(PropertyFilterOptions.All)
});
return (from PropertyDescriptor pd in propertyDescriptors
let dpd = DependencyPropertyDescriptor.FromProperty(pd)
where dpd != null
select dpd.DependencyProperty).ToList();
}
public static IEnumerable<DependencyProperty> GetUpdatedDependencyProperties(this DependencyObject obj)
{
return (from property in obj.GetDependencyProperties().Where(x => !x.ReadOnly)
let metaData = property.GetMetadata(obj.GetType())
let defaultValue = metaData.DefaultValue
let currentValue = obj.GetValue(property)
where currentValue != defaultValue
select property).ToList();
}
这将迫使XamlWriter.Save(dependencyObject)
序列化所有在XAML中更新的dependencyObject
属性。我很高兴您添加了这个属性-希望它能帮助其他同舟共济的人。GetDependencyProperties方法究竟从何而来?.Net framework源链接已经失效。以下是的4.8版的链接。Net框架:
foreach (var updatedProperty in dependencyObject.GetUpdatedDependencyProperties())
{
dependencyObject.SetValue(updatedProperty, dependencyObject.GetValue(updatedProperty));
}