如何在属性网格中加载xml文档

如何在属性网格中加载xml文档并将xml标记显示为属性网格中的属性

对于上面的问题,我在属性网格中得到了答案(通过Marc Gravell代码)但是由于可扩展对象转换器我得到了所有属性的“+”我需要删除它,如何删除

这不是一个简单的要求; 您必须编写一个包含自定义TypeConverter的包装类(对于XmlNode )(或者: ICustomTypeDescriptorTypeDescriptionProvider ,但TypeConverter最简单)。 然后编写一个自定义PropertyDescriptor (或几个)来表示虚假属性。 假设使用TypeConverter ,重写GetProperties以返回人工属性(对于值或子节点)。

TreeView向上构建它会更容易…


好; 这并不容易; 这是一个非常未经测试的起点 – 粗略且function不足,但无论如何它都在这里。

有关此处发生的事情的更多参考,请特别查看模拟属性的PropertyDescriptor提供属性的TypeConverter (尽管还有其他选项)。

其他一些可能有用的文章:

  • 数据绑定动态数据
  • 在运行时生成的属性(PropertyGrid.SelectedObject)
  • 如何在属性网格中显示动态对象?

码:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; using System.Xml; namespace DemoApp { class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); XmlDocument doc = new XmlDocument(); doc.LoadXml("dhij"); using (var grid = new PropertyGrid { Dock = DockStyle.Fill, SelectedObject = new XmlNodeWrapper(doc.DocumentElement)}) using (var form = new Form { Controls = {grid}}) { Application.Run(form); } } } } [TypeConverter(typeof(XmlNodeWrapperConverter))] class XmlNodeWrapper { private readonly XmlNode node; public XmlNodeWrapper(XmlNode node) { this.node = node; } class XmlNodeWrapperConverter : ExpandableObjectConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { List props = new List(); XmlElement el = ((XmlNodeWrapper)value).node as XmlElement; if (el != null) { foreach (XmlAttribute attr in el.Attributes) { props.Add(new XmlNodeWrapperPropertyDescriptor(attr)); } } foreach (XmlNode child in ((XmlNodeWrapper)value).node.ChildNodes) { props.Add(new XmlNodeWrapperPropertyDescriptor(child)); } return new PropertyDescriptorCollection(props.ToArray(), true); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { return destinationType == typeof(string) ? ((XmlNodeWrapper)value).node.InnerXml : base.ConvertTo(context, culture, value, destinationType); } } class XmlNodeWrapperPropertyDescriptor : PropertyDescriptor { private static readonly Attribute[] nix = new Attribute[0]; private readonly XmlNode node; public XmlNodeWrapperPropertyDescriptor(XmlNode node) : base(GetName(node), nix) { this.node = node; } static string GetName(XmlNode node) { switch (node.NodeType) { case XmlNodeType.Attribute: return "@" + node.Name; case XmlNodeType.Element: return node.Name; case XmlNodeType.Comment: return ""; case XmlNodeType.Text: return "(text)"; default: return node.NodeType + ":" + node.Name; } } public override bool ShouldSerializeValue(object component) { return false; } public override void SetValue(object component, object value) { node.Value = (string)value; } public override bool CanResetValue(object component) { return !IsReadOnly; } public override void ResetValue(object component) { SetValue(component, ""); } public override Type PropertyType { get { switch (node.NodeType) { case XmlNodeType.Element: return typeof(XmlNodeWrapper); default: return typeof(string); } } } public override bool IsReadOnly { get { switch (node.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Text: return false; default: return true; } } } public override object GetValue(object component) { switch (node.NodeType) { case XmlNodeType.Element: return new XmlNodeWrapper(node); default: return node.Value; } } public override Type ComponentType { get { return typeof(XmlNodeWrapper); } } } }