.NET PropertyGrid: доступ к экземплярам объектов и управление ими во время выполнения - PullRequest
1 голос
/ 07 ноября 2011

Я хотел бы получить доступ к object объектам через PropertyGrid и заставить их вести себя как реальные вещи, которые они представляют.Для игрушечного класса, такого как;

[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 через средство доступа Object, а затем заставить его вести себя как float в PropertyGrid, ачем стандартное object поведение, когда он ничего не может с этим поделать.

В качестве обходного пути я добавил следующий метод доступа:

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

, который позволяет мне манипулироватьобъект, но это не идеал.Возможно ли то, что я хочу сделать?

Ответы [ 2 ]

2 голосов
/ 07 ноября 2011

Это возможно.Вам необходимо реализовать ICustomTypeDescriptor и предоставить свои собственные экземпляры PropertyDescriptorsSystem.ComponentModel) - в этих дескрипторах свойств вы можете указать тип свойства - в вашем случае float.

1 голос
/ 08 ноября 2011

Я предлагаю вам реализовать свой собственный typeEditor для свойства ObjectBucket.Object. Это позволит вам показать форму редактора, где пользователь может указать тип и значение для этого свойства следующим образом:
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);
    }
}
...