如何在属性网格中加载 xml 文档 [英] How to load xml document in property grid
问题描述
如何在属性网格中加载xml文档并将xml标签显示为属性网格中的属性
How to load xml document in property grid and display the xml tags as properties in property grid
对于上述问题,我在属性网格中得到了答案(通过 Marc Gravell 代码),但由于可扩展对象转换器,我需要删除它的所有属性都得到+",如何删除
For the above question I got answer(by Marc Gravell code) in property grid but because of expandable object converter I'm getting "+" for all properties I need to remove it ,how to remove
推荐答案
那不是一个简单的请求;您必须编写一个具有自定义 TypeConverter
(或者:ICustomTypeDescriptor
或 TypeDescriptionProvider
)的包装类(用于 XmlNode
)code>,但 TypeConverter
是最简单的).然后编写一个自定义的 PropertyDescriptor
(或多个)来表示假属性.假设使用 TypeConverter
,覆盖 GetProperties
以返回人工属性(用于值或子节点).
That is not a simple request; you would have to write a wrapper class (for an XmlNode
) that has a custom TypeConverter
(alternatively: ICustomTypeDescriptor
or TypeDescriptionProvider
, but TypeConverter
is simplest). Then write a custom PropertyDescriptor
(or several) to represent the fake properties. Assuming TypeConverter
, override GetProperties
to return the artificial properties (for values or sub-nodes).
从 TreeView
...
好的;这不容易;这是一个非常未经测试的起点 - 粗糙且几乎没有功能,但无论如何都在这里.
OK; this is not easy; this is a very untested start point - crude and barely functional, but here it is anyway.
有关此处发生的事情的更多参考,请特别查看模拟属性的 PropertyDescriptor
和 提供 属性的 TypeConverter
(尽管对此还有其他选择).
For more reference on what is happening here, look in particular at PropertyDescriptor
which simulates properties, and TypeConverter
which provides the properties (although there are other options for this).
其他一些可能有帮助的文章:
Some other articles that may help:
代码:
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("<xml a=\"b\"><c>d<e f=\"g\">h</e>i</c>j</xml>");
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<PropertyDescriptor> props = new List<PropertyDescriptor>();
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); }
}
}
}
这篇关于如何在属性网格中加载 xml 文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!