假设我有以下不允许更改的类:
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;
}
现在我想通过将它们放入 PropertyGrid 来编辑这些数据。我创建了两个像这样的 Wrapper 类(http://msdn.microsoft.com/en-us/magazine/cc163816.aspx)
public class FieldsToPropertiesProxyTypeDescriptor : ICustomTypeDescriptor
{
private object _target;
// object to be 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 to the target object
}
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
// Gets the attributes of the target object
return TypeDescriptor.GetAttributes(_target, true);
}
string ICustomTypeDescriptor.GetClassName()
{
// Gets the class name of the 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
{
get { return _field; }
}
public override bool Equals(object obj)
{
FieldPropertyDescriptor other = obj as FieldPropertyDescriptor;
return other != null && other._field.Equals(_field);
}
public override int GetHashCode()
{
return _field.GetHashCode();
}
public override bool IsReadOnly
{
get { return false; }
}
public override AttributeCollection Attributes
{
get
{
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
{
get { return _field.DeclaringType; }
}
public override Type PropertyType
{
get { return _field.FieldType; }
}
public override object GetValue(object component)
{
if (component is FieldsToPropertiesProxyTypeDescriptor)
{
FieldsToPropertiesProxyTypeDescriptor proxy = (FieldsToPropertiesProxyTypeDescriptor)component;
return _field.GetValue(proxy.GetProxiedObject());
}
return _field.GetValue(component);
}
public override void SetValue(object component, object value)
{
if (component is FieldsToPropertiesProxyTypeDescriptor)
{
FieldsToPropertiesProxyTypeDescriptor proxy = (FieldsToPropertiesProxyTypeDescriptor)component;
_field.SetValue(proxy.GetProxiedObject(), value);
OnValueChanged(proxy.GetProxiedObject(), EventArgs.Empty);
return;
}
_field.SetValue(component, value);
OnValueChanged(component, EventArgs.Empty);
}
}
我可以在 PropertyGrid 中查看和编辑“m_newMember”,但我需要通过 FieldsToPropertiesProxyTypeDescriptor 包装对“m_baseData”的访问。我怎么能做到这一点。或者有没有更好的方法将字段包装到属性中?