.NET PropertyGrid:在运行时访问和操作Object实例

时间:2011-11-07 14:22:57

标签: c# .net winforms propertygrid

我想通过PropertyGrid访问object个对象,让它们表现为它们所代表的实际内容。对于玩具类,如;

[TypeConverter(typeof(ObjectBucket.ObjectBucketConverter))]
class ObjectBucket
{
    public object foo;

    [Browsable(true)]
    public object Object
    {
        get { return foo; }
        set { foo = value; }
    }

    private class ObjectBucketConverter : ExpandableObjectConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
        }
    }
}

我希望能够通过Object访问器设置float,然后让它在PropertyGrid中表现为float,而不是标准的object行为无能为力。

作为一种解决方法,我已将以下访问者放入其中;

[Browsable(true)]
public string ObjectStr
{
    get { return foo.ToString(); }
    set
    {
        try
        {
            foo = TypeDescriptor.GetConverter(foo.GetType()).ConvertFromInvariantString(value);
        }
        catch
        {
            return;
        }
    }
}

允许我操纵对象,但这并不理想。我想做什么甚至可能?

2 个答案:

答案 0 :(得分:2)

有可能。您需要实现ICustomTypeDescriptor并提供自己的PropertyDescriptors实例(在System.ComponentModel中) - 在这些属性描述符中,您可以指定属性类型 - 在您的情况下为float。

答案 1 :(得分:1)

我建议你为ObjectBucket.Object属性实现自己的typeEditor。 这将允许您显示编辑器表单,用户可以通过以下方式指定此属性的类型和值:
enter image description here

以下是实施框架:

class ObjectBucket {
    object foo;
    [Editor(typeof(ObjectUITypeEditor), typeof(UITypeEditor))]
    public object Object {
        get { return foo; }
        set { foo = value; }
    }
}
//...
class ObjectUIEditor : Form {
    public ObjectUIEditor(object editValue) {
        /* TODO Initialize editor*/
    }
    public object EditValue {
        get { return null; /* TODO GetValue from editor */} 
    }
}
//...
class ObjectUITypeEditor : System.Drawing.Design.UITypeEditor {
    System.Windows.Forms.Design.IWindowsFormsEditorService edSvc = null;
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object objValue)
        if(context != null && context.Instance != null && provider != null) {
            edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if(edSvc != null) {
                try {
                    ObjectUIEditor editor = new ObjectUIEditor(objValue);
                    if(edSvc.ShowDialog(editor) == DialogResult.OK) 
                        objValue = editor.EditValue;
                }
                catch { }
            }
        }
        return objValue;
    }
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
        if(context != null && context.Instance != null) 
            return UITypeEditorEditStyle.Modal;
        return base.GetEditStyle(context);
    }
}