Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XamlWriter.Save()未序列化DependencyProperties_C#_Wpf_Xaml_Xamlwriter_Uielementcollection - Fatal编程技术网

C# XamlWriter.Save()未序列化DependencyProperties

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

考虑来自my UserControl的以下XAML:

<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));
}