如何在属性网格中加载xml文档
如何在属性网格中加载xml文档并将xml标记显示为属性网格中的属性
对于上面的问题,我在属性网格中得到了答案(通过Marc Gravell代码)但是由于可扩展对象转换器我得到了所有属性的“+”我需要删除它,如何删除
这不是一个简单的要求; 您必须编写一个包含自定义TypeConverter
的包装类(对于XmlNode
)(或者: ICustomTypeDescriptor
或TypeDescriptionProvider
,但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("dhi j "); 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); } } } }