在属性网格上显示数据

时间:2014-03-08 05:38:37

标签: c# xml winforms propertygrid

想要在属性网格上显示xml文件中的提取数据。 XML文件看起来像这样:

<?xml version="1.0" encoding="utf-8" ?> 
<customer>
    <cust id="1">
        <id>120</id>
        <name>hello</name>

    </cust>
    <cust id="2">

        <name>hello12</name>
        <id>12012</id>
    </cust>
</customer>

现在我想在服务器ID为类别的属性网格上从XML中提取数据(即必须在一个类别中显示cust id =“1”,在第二个类别中显示cust id =“2”)

1 个答案:

答案 0 :(得分:1)

试试这段代码示例:

[TypeConverter(typeof(CustomerObjectConverter))]
public class Customer
{
    internal readonly int ServerId;
    public int Id { get; set; }
    public string Name { get; set; }

    public Customer(int serverId)
    {
        ServerId = serverId;
    }

    public override string ToString()
    {
        return Id + ", " + Name;
    }
}

public class CustomerCollection : CollectionBase, ICustomTypeDescriptor
{
    public CustomerCollection()
    {
    }

    public CustomerCollection(IEnumerable<Customer> collection)
    {
        foreach (var item in collection)
            Add(item);
    }

    public void Add(Customer emp)
    {
        List.Add(emp);
    }
    public void Remove(Customer emp)
    {
        List.Remove(emp);
    }
    public Customer this[int index]
    {
        get { return (Customer)List[index]; }
    }

    public String GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public String GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        return GetProperties();
    }

    public PropertyDescriptorCollection GetProperties()
    {
        PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null);

        for (int i = 0; i < List.Count; i++)
        {
            CustomersCollectionPropertyDescriptor pd = new CustomersCollectionPropertyDescriptor(this, i);
            pds.Add(pd);
        }
        return pds;
    }
}

internal class CustomersCollectionPropertyDescriptor : PropertyDescriptor
{
    private readonly CustomerCollection collection;
    private readonly int index = -1;

    public CustomersCollectionPropertyDescriptor(CustomerCollection coll, int idx)
        : base("#" + idx.ToString(), null)
    {
        collection = coll;
        index = idx;
    } 

    public override AttributeCollection Attributes
    {
        get { return new AttributeCollection(null); }
    }

    public override string Category
    {
        get { return "Server " + collection[index].ServerId; }
    }

    public override bool CanResetValue(object component)
    {
        return true;
    }

    public override Type ComponentType
    {
        get { return collection.GetType(); }
    }

    public override string DisplayName
    {
        get { return "Customer " + (index + 1); }
    }

    public override string Description
    {
        get { return "Customer"; }
    }

    public override object GetValue(object component)
    {
        return collection[index];
    }

    public override bool IsReadOnly
    {
        get { return true;  }
    }

    public override string Name
    {
        get { return "#" + index.ToString(); }
    }

    public override Type PropertyType
    {
        get { return collection[index].GetType(); }
    }

    public override void ResetValue(object component) {}

    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }

    public override void SetValue(object component, object value)
    {
    }
}

internal class CustomerObjectConverter : ExpandableObjectConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return false;
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        return destinationType == typeof(string) && value is Customer
                   ? value.ToString()
                   : base.ConvertTo(context, culture, value, destinationType);
    }
}

用法。将以下代码粘贴到包含PropertyGrid的表单的构造函数中,其名称为 propertyGrid

const string xmlString = "<customer><cust id=\"1\"><id>120</id><name>hello</name></cust><cust id=\"2\"><name>hello12</name><id>12012</id></cust></customer>";
XmlDocument xml = new XmlDocument();
xml.LoadXml(xmlString);
XmlNode root = xml["customer"];

CustomerCollection customers = new CustomerCollection();

foreach (XmlNode node in root.ChildNodes)
    customers.Add(new Customer(int.Parse(node.Attributes["id"].Value))
        {
            Id = int.Parse(node["id"].InnerText),
            Name = node["name"].InnerText
        });

propertyGrid.SelectedObject = customers;