c# - Fileds to Properties Proxy -
let's imagine have following classes not allowed change:
public class basetype { public uint32 m_basemember = 1; public bool m_basememberbool = false; } public class composedtype { public composedtype() { m_basedata = new basetype(); } public uint32 m_newmember = 2; public basetype m_basedata; }
now want edit data putting in propertygrid. created 2 wrapper classes ( http://msdn.microsoft.com/en-us/magazine/cc163816.aspx )
public class fieldstopropertiesproxytypedescriptor : icustomtypedescriptor { private object _target; // object described public fieldstopropertiesproxytypedescriptor(object target) { if (target == null) throw new argumentnullexception("target"); _target = target; } public object getproxiedobject() { return _target; } object icustomtypedescriptor.getpropertyowner(propertydescriptor pd) { return _target; // properties belong target object } attributecollection icustomtypedescriptor.getattributes() { // gets attributes of target object return typedescriptor.getattributes(_target, true); } string icustomtypedescriptor.getclassname() { // gets class name of target object return typedescriptor.getclassname(_target, true); } string icustomtypedescriptor.getcomponentname() { return typedescriptor.getcomponentname(_target, true); } typeconverter icustomtypedescriptor.getconverter() { return typedescriptor.getconverter(_target, true); } eventdescriptor icustomtypedescriptor.getdefaultevent() { return typedescriptor.getdefaultevent(_target, true); } propertydescriptor icustomtypedescriptor.getdefaultproperty() { return typedescriptor.getdefaultproperty(_target, true); } object icustomtypedescriptor.geteditor(type editorbasetype) { return typedescriptor.geteditor(_target, editorbasetype); } eventdescriptorcollection icustomtypedescriptor.getevents(attribute[] attributes) { return typedescriptor.getevents(_target, attributes); } eventdescriptorcollection icustomtypedescriptor.getevents() { return typedescriptor.getevents( _target ); } propertydescriptorcollection icustomtypedescriptor.getproperties() { return ((icustomtypedescriptor)this).getproperties(null); } propertydescriptorcollection icustomtypedescriptor.getproperties( attribute[] attributes) { bool filtering = (attributes != null && attributes.length > 0); propertydescriptorcollection props = new propertydescriptorcollection(null); foreach (propertydescriptor prop in typedescriptor.getproperties(_target, attributes, true)) { props.add(prop); } foreach (fieldinfo field in _target.gettype().getfields()) { fieldpropertydescriptor fielddesc = new fieldpropertydescriptor(field); if (!filtering || fielddesc.attributes.contains(attributes)) props.add(fielddesc); } return props; } } public class fieldpropertydescriptor : propertydescriptor { private fieldinfo _field; public fieldpropertydescriptor(fieldinfo field) : base(field.name, (attribute[])field.getcustomattributes(typeof(attribute), true)) { _field = field; } public fieldinfo field { { return _field; } } public override bool equals(object obj) { fieldpropertydescriptor other = obj fieldpropertydescriptor; return other != null && other._field.equals(_field); } public override int gethashcode() { return _field.gethashcode(); } public override bool isreadonly { { return false; } } public override attributecollection attributes { { if (_field.fieldtype.isclass || _field.fieldtype.isarray) { attribute[] expandable = new attribute[1]; expandable[0] = new expandableobjectattribute(); return attributecollection.fromexisting(base.attributes, expandable); } return base.attributes; } } public override void resetvalue(object component) { } public override bool canresetvalue(object component) { return false; } public override bool shouldserializevalue(object component) { return true; } public override type componenttype { { return _field.declaringtype; } } public override type propertytype { { return _field.fieldtype; } } public override object getvalue(object component) { if (component fieldstopropertiesproxytypedescriptor) { fieldstopropertiesproxytypedescriptor proxy = (fieldstopropertiesproxytypedescriptor)component; return _field.getvalue(proxy.getproxiedobject()); } return _field.getvalue(component); } public override void setvalue(object component, object value) { if (component fieldstopropertiesproxytypedescriptor) { fieldstopropertiesproxytypedescriptor proxy = (fieldstopropertiesproxytypedescriptor)component; _field.setvalue(proxy.getproxiedobject(), value); onvaluechanged(proxy.getproxiedobject(), eventargs.empty); return; } _field.setvalue(component, value); onvaluechanged(component, eventargs.empty); } }
i can see , edit 'm_newmember' in propertygrid need wrap access 'm_basedata' via fieldstopropertiesproxytypedescriptor. how achieve this. or there better way wrap fields properties?
you can change attributes of given class @ runtime without changing class. write custom typeconverter , set classes, this:
typedescriptor.addattributes(typeof(composedtype), new typeconverterattribute(typeof(fieldsexpandableobjectconverter))); typedescriptor.addattributes(typeof(basetype), new typeconverterattribute(typeof(fieldsexpandableobjectconverter)));
with following typeconverter (re-using fielddescriptor class):
public class fieldsexpandableobjectconverter : expandableobjectconverter { public override propertydescriptorcollection getproperties(itypedescriptorcontext context, object value, attribute[] attributes) { list<propertydescriptor> properties = new list<propertydescriptor>(base.getproperties(context, value, attributes).oftype<propertydescriptor>()); if (value != null) { foreach (fieldinfo field in value.gettype().getfields()) { fieldpropertydescriptor fielddesc = new fieldpropertydescriptor(field); { properties.add(fielddesc); } } } return new propertydescriptorcollection(properties.toarray()); } }
Comments
Post a Comment