我正在调整Winforms应用程序。该应用程序有一个 Form 其中包含一个 PropertyGrid. 。对象分配给 SelectedObject 属性使属性网格显示对象的属性。

分配的对象的类型具有携带的属性 EditorAttribute 指定 UITypeEditor.

此实施 UITypeEditor 返回 UITypeEditorEditStyle.Drop 在其替代 GetEditStyle 方法。它的 EditValue 方法显示 ListBox 可以从中分配实例属性的值。

到目前为止,一切都很好。

现在,我有一个其他要求,要求根据列表中的可用项目根据持有的其他状态进行修改 Form 主持 PropertyGrid. 。我无法弄清楚如何将此上下文信息获取到 EditValue 方法。

似乎没有什么 context 即使我尝试将其施放到更具体的类型中,参数也是如此。我也无法确定如何添加其他服务以从 provider.

有任何想法吗?

有帮助吗?

解决方案

我想知道您要做什么会更好 TypeConverter 通过 GetStandardValues?但是无论哪种方式 context.Instancecontext.PropertyDescriptor 似乎 在快速测试中填充 GetEditStyleEditValue):

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
class MyData
{
    [Editor(typeof(MyEditor), typeof(UITypeEditor))]
    public string Bar { get; set; }

    public string[] Options { get; set; }
}
class MyEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        // break point here; inspect context
        return UITypeEditorEditStyle.DropDown;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        // break point here; inspect context
        return base.EditValue(context, provider, value);
    }

}
class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form
        {
            Controls =
            {
                new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = new MyData()
                }
            }
        });
    }
}

或作为类型连接器:

using System;
using System.ComponentModel;
using System.Windows.Forms;

class MyData
{
    [TypeConverter(typeof(MyConverter))]
    public string Bar { get; set; }

    public string[] Options { get; set; }
}
class MyConverter : StringConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        MyData data = (MyData)context.Instance;
        if(data == null || data.Options == null) {
            return new StandardValuesCollection(new string[0]);
        }
        return new StandardValuesCollection(data.Options);
    }
}
class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form
        {
            Controls =
            {
                new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = new MyData()
                }
            }
        });
    }
}

其他提示

我当时处于类似的状态,我想将一个对象注入我的自定义UityPeeditor的构造函数。

我遵循尼古拉斯·卡迪尔哈克(Nicolas Cadilhac)的评论 这里, ,给他所有的荣誉。它使用TypeDescriptionProvider。

这是完整的代码集。

class Foo
{
    public Foo() { Bar = new Bar(); }
    public Bar Bar { get; set; }
}

class Bar
{
    public string Value { get; set; }
}

class BarTypeDescriptionProvider : TypeDescriptionProvider
{
    private TypeDescriptionProvider _baseProvider;
    string _extraParam;

    public BarTypeDescriptionProvider(Type t, string extraParam)
    {
        this._extraParam = extraParam;
        _baseProvider = TypeDescriptor.GetProvider(t);
    }

    public string ExtraParam
    { 
        get { return _extraParam; } 
    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        return new BarTypeDescriptor(this, _baseProvider.GetTypeDescriptor(objectType, instance), objectType);
    }
}


class BarTypeDescriptor : CustomTypeDescriptor
{
    private Type _objectType;
    private BarTypeDescriptionProvider _provider;

    public BarTypeDescriptor(BarTypeDescriptionProvider provider,  ICustomTypeDescriptor descriptor, Type objectType): base(descriptor)
    {
        if (provider == null) throw new ArgumentNullException("provider");
        if (descriptor == null)
            throw new ArgumentNullException("descriptor");
        if (objectType == null)
            throw new ArgumentNullException("objectType");
        _objectType = objectType;
        _provider = provider;
    }

    public override object GetEditor(Type editorBaseType)
    {
        return new BarEditor(_provider.ExtraParam);
    }
}


class BarEditor : UITypeEditor
{
    private string _extraParam;
    public BarEditor(string x)
        : base()
    {
        _extraParam = x;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        MessageBox.Show(_extraParam);
        return base.EditValue(context, provider, value);
    }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        string extraParam = "Extra param from main form";

        TypeDescriptor.AddProvider(new BarTypeDescriptionProvider(typeof(Bar), extraParam), typeof(Bar));

        this.propertyGrid1.SelectedObject = new Foo();
    }
}

迈克尔

在覆盖的编辑方法中, context.Container 将提供编辑器所属的对象。这 context.Container.Components 财产将列出包括表格及其所有子女的所有控件。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top