XDocument实时更新的viewmodel

时间:2013-01-23 22:05:07

标签: c# xml-parsing linq-to-xml viewmodel visual-studio-sdk

有没有人知道一种简单的方法来保持视图模型与不断变化的XDocument同步? XDocument来自Microsoft.VisualStudio.XmlEditor.XmlModel类(http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.xmlmodel.aspx)。当用户在visual studio编辑器中更改文本时,会不断更新相同的XDocument。

我不希望每次将整个xml解析为对象时使用序列化进行解析。该文件非常,这将是一个巨大的性能瓶颈。

这个问题在某种程度上类似于我的问题,但是填写“(帮助者)”的内容是什么? ViewModel on top of XDocument

要求: - 当XDocument树中的某些内容发生更改时,必须更新viewmodel,并且必须应用最小更改。 - 更改对象的子项时的事件。 - 当存在多个相同的子标签时的Observablecollections - 必须重复使用对象,每次从我的自定义类访问对象时都不会有新元素。因此必须使用属性来保存xml中生成的对象。必须使用新子项更新对象。

是否有可以轻松完成此任务的框架或其他内容?我想很多人已经做过这样的事了,我不想重新发明轮子。

我希望这个问题有点清楚。

1 个答案:

答案 0 :(得分: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));

ObotableCollection本身通过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);
  }
}

请注意更改和更改正在冒泡,因此您只能查看XDocument.Root XElement或Model.Element XElement。

有点过于简单,我希望能让你知道它的外观。现在,.NET Framwork就是你的。

我找到了很好的例子: