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

发布于 2024-12-14 06:05:58 字数 1124 浏览 2 评论 0原文

我想通过 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);
        }
    }
}

我希望能够通过对象访问器设置一个 float ,然后让它在 PropertyGrid 中充当 float ,而不是标准的 object 无法对其执行任何操作的行为。

作为解决方法,我放入了以下访问器;

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

这允许我操纵该对象,但并不理想。我想做的事情可能吗?

I'm would like to access object objects through a PropertyGrid and have them behave as the actual things they represent. For a toy class such as;

[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);
        }
    }
}

i'd like to be able to set say a float through the Object accessor, and then have it behave as a float in a PropertyGrid, rather than the standard object behaviour of being able to do nothing to it.

As a work around I've put the following accessor in;

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

which allows me to manipulate the object, but it not ideal. Is what I want to do even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2024-12-21 06:05:58

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

It is possible. You need to implement ICustomTypeDescriptor and supply your own instances of PropertyDescriptors (in System.ComponentModel) - in these property descriptors you can specify the property type - in your case float.

温馨耳语 2024-12-21 06:05:58

我建议您为 ObjectBucket.Object 属性实现自己的 typeEditor。
这将允许您显示编辑器表单,用户可以通过以下方式指定该属性的类型和值:
在此处输入图像描述

这是实现框架:

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);
    }
}

I suggest you to implement your own typeEditor for the ObjectBucket.Object property.
That will allow you to show editor form where an user can specify the type and the value for this property in the following manner:
enter image description here

Here is the implementation skeleton:

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文