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.
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.
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 ....).
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.
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();
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;
bind to indexer
Fei Xu
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
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
Dorin.
Joey Joey
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.