Search code examples
c#xmlwinformspropertygrid

Displaying data on property grid


Would like to display extracted data from xml file on property grid. XML file looks something like this:

<?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>

Now I want to extract data from XML on a property grid with server id as category(i.e it has to display cust id="1" in one category and cust id="2" in second category)


Solution

  • Try this code sample:

    [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);
        }
    }
    

    Usage. Paste the following code into constructor of the form containing PropertyGrid with the name 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;