using System;

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace WindowsApplicationDataBinding

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            m_DataGridView.DataSource = ToDataSource(GenerateData()); ;           

        }

 

        public IList<DictionaryToRowWrapper> ToDataSource(IEnumerable<IDictionary<string, object>> enumerable)

        {

            IEnumerator<IDictionary<string, object>> enumerator = enumerable.GetEnumerator();

            List<DictionaryToRowWrapper> list = new List<DictionaryToRowWrapper>();

            while(enumerator.MoveNext())

            {

                list.Add(new DictionaryToRowWrapper(enumerator.Current));

            }

 

            return list;

        }

 

        public IEnumerable<IDictionary<string, object>> GenerateData()

        {

            for (int i = 0; i < 10; i++)

            {

                // or you could use new Hashtable();

                Dictionary<string, object> dict = new Dictionary<string, object>();

                dict["1ID"] = Guid.NewGuid();

                dict["Name"] = "Name_" + i;

                dict["Index"] = i;

                dict["IsEven"] = (i % 2 == 0);

                yield return dict;

            }

        }

 

        public class DictionaryToRowWrapper : ICustomTypeDescriptor

        {

            private IDictionary<string, object> m_Dictionary;

 

            public DictionaryToRowWrapper(IDictionary<string, object> dictionary)

            {

                m_Dictionary = dictionary;

            }

 

            #region ICustomTypeDescriptor

 

            public AttributeCollection GetAttributes()

            {

                return new AttributeCollection(null);

            }

 

            public string GetClassName()

            {

                return null;

            }

 

            public string GetComponentName()

            {

                return null;

            }

 

            public TypeConverter GetConverter()

            {

                return null;

            }

 

            public EventDescriptor GetDefaultEvent()

            {

                return null;

            }

 

            public PropertyDescriptor GetDefaultProperty()

            {

                return null;

            }

 

            public object GetEditor(Type editorBaseType)

            {

                return null;

            }

 

            public EventDescriptorCollection GetEvents()

            {

                return new EventDescriptorCollection(null);

            }

 

            public EventDescriptorCollection GetEvents(Attribute[] attributes)

            {

                return new EventDescriptorCollection(null);

            }

 

            public PropertyDescriptorCollection GetProperties()

            {

                return ((ICustomTypeDescriptor)this).GetProperties(null);

            }

 

            public PropertyDescriptorCollection GetProperties(Attribute[] attributes)

            {

                PropertyDescriptor[] properties =

                    new PropertyDescriptor[m_Dictionary.Count];

 

                int index = 0;

                foreach (KeyValuePair<string, object> pair in m_Dictionary)

                {

                    properties[index] =

                        new StringPropertyDescriptor(pair.Key, pair.Value);

                    index++;                   

                }

 

                return new PropertyDescriptorCollection(properties);               

            }

 

            public object GetPropertyOwner(PropertyDescriptor pd)

            {

                return this;

            }

 

            #endregion ICustomTypeDescriptor

 

            #region PropertyDescriptor

 

            private class StringPropertyDescriptor : PropertyDescriptor

            {

                private readonly string m_Name;

                private readonly object m_Value;

 

                public StringPropertyDescriptor(string name, object val)

                    : base(name, new Attribute[]{})

                {

                    m_Name = name;

                    m_Value = val;

                }

 

                public override bool CanResetValue(object component)

                {

                    return false;

                }

 

                public override void ResetValue(object component)

                {

                   

                }

 

                public override object GetValue(object component)

                {

                    return ((DictionaryToRowWrapper)component).m_Dictionary[m_Name];

                }

 

                public override void SetValue(object component, object value)

                {

                    ((DictionaryToRowWrapper)component).m_Dictionary[m_Name] = value;

                }

 

                public override bool ShouldSerializeValue(object component)

                {

                    return false;

                }

 

                public override Type ComponentType

                {

                    get { return typeof (DictionaryToRowWrapper); }

                }

 

                public override bool IsReadOnly

                {

                    get { return false; }

                }

 

                public override Type PropertyType

                {

                    get { return m_Value.GetType(); }

                }

 

                public override bool Equals(object obj)

                {

                    if (obj is StringPropertyDescriptor)

                    {

                        return ((StringPropertyDescriptor) obj).m_Name == m_Name;

                    }

                    return base.Equals(obj);

                }

 

                public override int GetHashCode()

                {

                    return m_Name.GetHashCode();

                }

            }

            #endregion PropertyDescriptor

        }

    }

}