2015-12-11 9 views
0

Я использую шаблон mvvm в приложении wpf. Как datasource у меня XDocument. В UI я привязываю элементы управления к значениям XElements и XAttribute из этого XDocument. f.ex.Реализация XElement, XAttribute + IDataErrorInfo для привязки в приложении wpf

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

Это позволяет мне иметь данные в единственном месте - в XDoc и позволяет избежать преобразования данных из пользовательских моделей в XML.

Теперь мне нужно расширить функциональность модели с помощью IDataErrorInfo для реализации уведомления об ошибке. Поэтому мне нужно добавить интерфейс к классам XElement и XAttribute .net. У меня есть 2 решения: 1) адаптер шаблона для xelement и xattribute, который будет иметь адаптацию, реализацию интерфейса IDataErrorInfo и значение setter \ getter для значения xelement \ xattribute. Слабость - мне нужно создать объекты-адаптеры для всех элементов управления входным интерфейсом и привязать к нему. 2) Создайте дочерний класс и наследуйте от XElement \ XAttribute с реализацией интерфейса. Weekness - мне нужно преобразовать все xelements и xattributes в мой дочерний класс. Какой способ лучше?

+0

Deserialize ваш XML в классы, которые реализуют интерфейс. Это самый простой способ сделать это. Попробуйте это в небольшом прототипе. – Will

+0

в вашем случае, если у меня сложная структура xml (по крайней мере 15 уровней), мне нужно будет определить множество классов для десериализации, привязать к объектам вместо xdoc и иметь много данных sourcez –

+0

Eh, затем создать граф объектов и выполнить перевод самостоятельно. – Will

ответ

0

Лучший способ, я думаю, состоит в том, чтобы наследовать от XElement/XAttribute и добавить интерфейс, в котором вы нуждаетесь. Я создал 2 дочерних класса 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>(); 
     } 
}