1

Does anybody know an easy way to keep a viewmodel in sync with an XDocument which is constantly changing? The XDocument is coming from the Microsoft.VisualStudio.XmlEditor.XmlModel class (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.xmlmodel.aspx). The same XDocument is constantly updated when a user is changing text in the visual studio editor.

I don't want to use serialisation to parse every time the whole xml into objects. The document is very, and that would be a big performance bottleneck.

This question is somehow similar to my question, but what to fill in on "(helper)"? ViewModel on top of XDocument

Requirements: - The viewmodel must be updated when something in the XDocument tree is changed, and minimum changes must be applied. - Events when a child of an object is changed. - Observablecollections when there are multiple same child tags - Objects must be reused, no new elements each time objects are accessed made from my custom classes. So properties must be used to hold the generated object from xml. The object must be updated with the new childs.

Is there a framework or something available to do this task in an easy way? I think many people have already done something like this, and I don't want to re-invent the wheel.

I hope this question is a little bit clear.

4

1 回答 1

0

您可以围绕 XElement 编写 ViewModel。

例如,

public class Model {

   protected XElement Element {
     get; set;
   }

   public Model() : this(null) { }

   public Model(XElement element) {
     // do some validation (XName)element.Name
     this.Element = element ?? new XElement("Model");
   }

   public string Name {
     get {
       return (string)Element.Attribute("Name");
     }
     set {
       // null: attribute is removed
       Element.SetAttributeValue(value);
     }
   }
}

你的 XML:

<Model Name="Marilyn" />

使用您的 XDocument,您可以阅读您的元素:

source.Select(xElement => new Model(xElement));

ObservableCollection 本身由 INotifyPropertyChanged 模式通知:

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
    var handler = PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));
}

在您的模型中,您会收到您在构造函数中分配的 XObject.Change 和 .Changed 事件的通知:

public Model() : this(null) {
  // call public Model(XElement element = null)
}

public Model(XElement element) {
  // do some validation (XName)element.Name
  this.Element = element ?? new XElement("Model");
  //this.Element.Changing += Element_Changing;
  this.Element.Changed += Element_Changed;
}

现在您可以将 XElement 更改连接到 INotifyProperty 更改:

protected void Element_Changed(object sender, XObjectChangeEventArgs ea) {
  var attribute = sender as XAttribute;
  if (attribute != null && attribute.Parent == this.Element) {
    // only attributes of this element (and not the nested elements)
    // the attribute name is assumed to be exactly same as property name 'Name'
    OnPropertyChanged(attribute.Name);
  }
}

请注意,Changed 和 Changed 正在冒泡,因此您只能观看您的 XDocument.Root XElement 或 Model.Element XElement。

有点过于简单了,我希望让你知道它可能是什么样子。现在,.NET 框架就是你的了。

我在以下位置找到了很好的例子:

于 2013-01-23T23:07:21.177 回答