bind to indexer

Hi,

It's possible to bind to a indexer (ex: a["name"]) in VS 2005 beta2
(specially for datagridview)




Answer this question

bind to indexer

  • Fei Xu

    Hi,

    I have a class that contains a dictionary and I'm making the binding at run-time. I implementet a solution but is not very elegant (I contructed a wrapper class with properties like: column1, column2 ...). From what I saw datagridview use internal some PropertyDescriptor. One ideea is to create my custom propertydescriptor class, but I cannot set the DataGridView to use some customPropertyDescriptor.

    Dorin.

  • Alex - IntraLAN

    OK - I'm still not clear on what you're trying to do.  From what you've described you have a Dictionary with a string indexer but what are you trying to display and how do you want to display it   For example, do you want to display all the values for the indexer in a DataGridView


    Joe Stegman
    The Windows Forms Team
    Microsoft Corp.

    This posting is provided "AS IS" with no warranties, and confers no rights.


  • cloudycity

    here is an example:

    public class Entity
    {
        private Dictionary<string, object> values;
        private EntityModel model; //information about the fields stored in this entity

       public this[string]
        {
                 get
                    {
                          object val;
                            values.TryGetValue(value, out val);
                             return val;
                    }          
                    set { .....}
         }
    }

    For example if model if person we can have the keys: name, surname ......., and I what to link this to a DataGridView at runtime (entity has some mechanism to save in database, files, xml ....).

    Dorin.





  • Oleksiy

    As Mark indicated, this isn't possible in that you can't directly bind to the indexer.  What is it you're trying to do - there may be an indirect way to do it

    Joe Stegman
    The Windows Forms Team
    Microsoft Corp.

    This posting is provided "AS IS" with no warranties, and confers no rights.


  • Amnesiasoft

    thanks for example. it's working fine :).

    Dorin.

  • Joey Joey

    an the values I what to display i decide at runtime also (normaly I display only essential information, not all values).

    Dorin.

  • Ralf G

    Regarding the DataGridView - it doesn't support binding to an indexer.

    -mark
    DataGridView Program Manager
    Microsoft
    This post is provided "as-is"


  • Wolf5

    OK - you may be looking for something like the sample below - it takes virtual properties from a "model" and presents them to the DataGridView as "real" properties.  It involves implementing ICustomTypeDescriptor - and although a bit complex this is extremely powerful (and how ADO.NET does a similar thing).  It should be fairly simple to adapt your Entity type to this:


    class EntitySample : ICustomTypeDescriptor
    {
        Dictionary<string, object>  _values;
        Dictionary<string, Type>    _model;
        Type                        _type;

        public EntitySample()
        {
            _values = new Dictionary<string, object>();
            _model = new Dictionary<string, Type>();
            _type = this.GetType();

            /* Add sample properties */
            AddPropertyToModel("StringProp", typeof(string));
            AddPropertyToModel("IntProp", typeof(int));
            AddPropertyToModel("FloatProp", typeof(float));
            AddPropertyToModel("EnumProp", typeof(DockStyle));
            AddPropertyToModel("BoolProp", typeof(bool));
        }

        public void AddPropertyToModel(string name, Type propertyType)
        {
            _model.Add(name, propertyType);
        }

        public object this[string name]
        {
            get
            {
                object  val;
                return (_values.TryGetValue(name, out val) val : null);
            }
            set { _values[name] = value;  }
        }

        public PropertyDescriptorCollection GetProperties()
        {
            return this.GetProperties(null);
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            PropertyDescriptor[]        props = new PropertyDescriptor[_model.Count];
            int                         idx=0;

            foreach (KeyValuePair<string, Type> prop in _model)
            {
                /* Ad Virtual Properties */
                props[idx++] = new EntityPropertyDescriptor(_type, prop.Key, prop.Value);
            }
           
            /* Also add properties on this type */
            PropertyDescriptorCollection pdc = new PropertyDescriptorCollection(props, false);

            foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(this, attributes, true))
            {
                pdc.Add(pd);
            }

            return pdc;
        }

        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        public override string ToString()
        {
            string result = string.Empty;

            foreach (KeyValuePair<string, object> prop in _values)
            {
                if (result != string.Empty)
                {
                    result += "; ";
                }

                result += (prop.Key + ": ");
                result += ((null == prop.Value) "null" : prop.Value);
            }

            return result;
        }

        #region ICustomTypeDescriptor Members (TypeDescriptor fallbacks)

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

        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(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, null);
        }

        #endregion
    }

    #region Entity Property Descriptor

    class EntityPropertyDescriptor : PropertyDescriptor
    {
        Type                        _componentType;
        Type                        _propertyType;
        string                      _name;

        public EntityPropertyDescriptor(Type parentType, string name, Type propertyType) : base(name, null)
        {
            _componentType = parentType;
            _name = name;
            _propertyType = propertyType;
        }

        public override Type ComponentType
        {
            get { return _componentType; }
        }

        public override Type PropertyType
        {
            get { return _propertyType; }
        }

        public override object GetValue(object component)
        {
            return (component as EntitySample)[_name];
        }

        public override void SetValue(object component, object value)
        {
            (component as EntitySample)[_name] = value;
        }

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

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

        public override void ResetValue(object component)
        {
            SetValue(component, null);
        }

        public override bool IsReadOnly
        {
            get { return false; }
        }
    }
    #endregion

     



    To see this work as is, you can bind it to a DataGridView:


    BindingSource   _bs;
    _bs = new BindingSource();
    _bs.DataSource = new EntitySample();

    this.dataGridView1.DataSource = _bs;
     



    Joe Stegman
    The Windows Forms Team
    Microsoft Corp.

    This posting is provided "AS IS" with no warranties, and confers no rights.


  • bind to indexer