0

I use mvvm pattern in wpf app. As datasource i've XDocument. In UI i bind controls to XElements and XAttribute's values from this XDocument. f.ex.

<TextBox Text={Binding XElement[TitleNode].XElement[Title].Value} />

It allows me to have data in only place - in XDoc and allows to avoid data conversion from custom models to xml.

Now I need to extend functionality of model with IDataErrorInfo to realize error notification. So i need to add interface to XElement and XAttribute .net classes. i've 2 decisions: 1) pattern adapter for xelement and xattribute, that will have adaptee, realiztion of interface IDataErrorInfo and Value setter\getter for xelement\xattribute's value. Weakness - i need create adapter-objects for all UI input control and bind to it. 2) Create child class and inherite from XElement\XAttribute with interface realization. Weekness - i need to convert all xelements and xattributes to my child class. What way is better?

vitm
  • 473
  • 1
  • 3
  • 12
  • Deserialize your xml into classes that implement the interface. That's the easiest way to do it. Try it in a small prototype. –  Dec 11 '15 at 21:40
  • in your case if i have difficult structure of xml (15 levels at least), i will have to define many classes for deserialization, bind to objects instead of xdoc and have many data sourcez – vitm Dec 13 '15 at 06:48
  • Eh, then create an object graph and do the translation yourself. –  Dec 14 '15 at 14:00

1 Answers1

0

The best way I guess is to inherite from XElement/XAttribute and add interface you need. I created 2 child class XElementCustom and XAttributeCustom. And in constructor the whole tree is recreated recursively That's my realization:

    /// <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>();
        }
}
vitm
  • 473
  • 1
  • 3
  • 12