質問

WinFormsアプリケーションを微調整しています。このアプリケーションには Form それにはaが含まれます PropertyGrid. 。オブジェクトはに割り当てられます SelectedObject プロパティグリッドがオブジェクトのプロパティを表示するようにプロパティ。

割り当てられたオブジェクトのタイプには、 EditorAttribute 指定a UITypeEditor.

のこの実装 UITypeEditor 戻り値 UITypeEditorEditStyle.Drop そのオーバーライドで GetEditStyle 方法。これは EditValue メソッドはaを表示します 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のコンストラクターにオブジェクトを注入したかったのです。

私はニコラス・キャディルハックのコメントに従いました ここ, 、彼にすべての信用を与えます。 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();
    }
}

マイケル

オーバーライドされたeditvalueメソッドでは、 context.Container 編集者が属するオブジェクトを提供します。 context.Container.Components プロパティは、フォームとそのすべての子供を含むすべてのコントロールをリストします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top