Mvvm XElement、XAttribute和x2B的再化;用于在wpf应用程序中绑定的IDataErrorInfo

Mvvm XElement、XAttribute和x2B的再化;用于在wpf应用程序中绑定的IDataErrorInfo,mvvm,binding,xelement,idataerrorinfo,xattribute,Mvvm,Binding,Xelement,Idataerrorinfo,Xattribute,我在wpf应用程序中使用mvvm模式。作为数据源,我有XDocument。在UI中,我将控件绑定到此XDocument中的XElements和XAttribute的值。 f、 前 它允许我只在XDoc中放置数据,并允许避免从自定义模型到xml的数据转换 现在我需要使用IDataErrorInfo扩展模型的功能,以实现错误通知。所以我需要向XElement和XAttribute.net类添加接口。 我有两个决定: 1) xelement和xattribute的模式适配器,将具有adaptee、

我在wpf应用程序中使用mvvm模式。作为数据源,我有XDocument。在UI中,我将控件绑定到此XDocument中的XElements和XAttribute的值。 f、 前


它允许我只在XDoc中放置数据,并允许避免从自定义模型到xml的数据转换

现在我需要使用IDataErrorInfo扩展模型的功能,以实现错误通知。所以我需要向XElement和XAttribute.net类添加接口。 我有两个决定: 1) xelement和xattribute的模式适配器,将具有adaptee、接口IDataErrorInfo的实现以及xelement\xattribute值的值设置器\getter。弱点-我需要为所有UI输入控件创建适配器对象并绑定到它。 2) 创建子类并通过接口实现从XElement\X属性继承。Weekness-我需要将所有Xelement和xattributes转换为我的孩子类。
什么方法更好?

我想最好的方法是继承XElement/XAttribute并添加所需的接口。 我创建了两个子类XElementCustom和XAttributeCustom。在构造函数中,整个树是递归地重新创建的 这就是我的体会:

    /// <summary>
    /// Наследник XML с реализацией INotifyPropertyChanged
    /// </summary>
    public class XElementCustom : XElement, INotifyPropertyChanged, IDataErrorInfo, IDataErrorInfoValidating
    {
public XElementCustom(XElement sourceElement)
            :base(sourceElement.Name.LocalName)
        {

            if (sourceElement.Elements().Any())
            {
                foreach (var element in sourceElement.Elements())
                {
                    this.Add(new XElementCustom(element));
                }
            }
            else
            {
                this.Value = sourceElement.Value;
            }

            foreach (var attribute in sourceElement.Attributes())
            {
                this.Add(new XAttributeCustom(attribute));
            }

            _changedProperties = new List<string>();
        }
}
//
///已更改XML的无效属性
/// 
公共类XElementCustom:XElement、INotifyPropertyChanged、IDataErrorInfo、IDataErrorInfo
{
公共XElementCustom(XElement源元素)
:base(sourceElement.Name.LocalName)
{
if(sourceElement.Elements().Any())
{
foreach(sourceElement.Elements()中的var元素)
{
添加(新的XElementCustom(元素));
}
}
其他的
{
this.Value=sourceElement.Value;
}
foreach(sourceElement.Attributes()中的var属性)
{
添加(新的XAttributeCustom(属性));
}
_changedProperties=新列表();
}
}

将xml反序列化为实现接口的类。这是最简单的方法。在你的例子中,如果我有困难的xml结构(至少15层),我将不得不定义许多类进行反序列化,绑定到对象而不是xdoc,并有许多数据源ZEH,然后创建一个对象图并自己进行转换。
    /// <summary>
    /// Наследник XML с реализацией INotifyPropertyChanged
    /// </summary>
    public class XElementCustom : XElement, INotifyPropertyChanged, IDataErrorInfo, IDataErrorInfoValidating
    {
public XElementCustom(XElement sourceElement)
            :base(sourceElement.Name.LocalName)
        {

            if (sourceElement.Elements().Any())
            {
                foreach (var element in sourceElement.Elements())
                {
                    this.Add(new XElementCustom(element));
                }
            }
            else
            {
                this.Value = sourceElement.Value;
            }

            foreach (var attribute in sourceElement.Attributes())
            {
                this.Add(new XAttributeCustom(attribute));
            }

            _changedProperties = new List<string>();
        }
}