2009-06-19 9 views
26

私のリストは<です>(私のカスタムクラス)。このリストの特定の項目をPropertyGridコントロールのボックスに表示します。ボックスの最後に[...]ボタンがあります。クリックすると、リストから項目の1つを選択できるフォームが開きます。閉じられると、PropertyGridは選択された値を反映するように更新されます。フォームを開くカスタムPropertyGridエディタアイテムを作成する方法は?

助けてください。

答えて

60

あなたはそれを表示するには、IWindowsFormsEditorServiceサービスを使用して、モーダルUITypeEditorを実装する必要があります。

using System.ComponentModel; 
using System.Drawing.Design; 
using System.Windows.Forms; 
using System.Windows.Forms.Design; 
using System; 

class MyType 
{ 
    private Foo foo = new Foo(); 
    public Foo Foo { get { return foo; } } 
} 

[Editor(typeof(FooEditor), typeof(UITypeEditor))] 
[TypeConverter(typeof(ExpandableObjectConverter))] 
class Foo 
{ 
    private string bar; 
    public string Bar 
    { 
     get { return bar; } 
     set { bar = value; } 
    } 
} 
class FooEditor : UITypeEditor 
{ 
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 
    public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value) 
    { 
     IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; 
     Foo foo = value as Foo; 
     if (svc != null && foo != null) 
     {    
      using (FooForm form = new FooForm()) 
      { 
       form.Value = foo.Bar; 
       if (svc.ShowDialog(form) == DialogResult.OK) 
       { 
        foo.Bar = form.Value; // update object 
       } 
      } 
     } 
     return value; // can also replace the wrapper object here 
    } 
} 
class FooForm : Form 
{ 
    private TextBox textbox; 
    private Button okButton; 
    public FooForm() { 
     textbox = new TextBox(); 
     Controls.Add(textbox); 
     okButton = new Button(); 
     okButton.Text = "OK"; 
     okButton.Dock = DockStyle.Bottom; 
     okButton.DialogResult = DialogResult.OK; 
     Controls.Add(okButton); 
    } 
    public string Value 
    { 
     get { return textbox.Text; } 
     set { textbox.Text = value; } 
    } 
} 
static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Form form = new Form(); 
     PropertyGrid grid = new PropertyGrid(); 
     grid.Dock = DockStyle.Fill; 
     form.Controls.Add(grid); 
     grid.SelectedObject = new MyType(); 
     Application.Run(form); 
    } 
} 

注:プロパティのコンテキスト(親オブジェクトなど)についての何かをアクセスする必要がある場合、それはありますITypeDescriptorContextEditValue)の内容は次のとおりです。関連するPropertyDescriptorInstanceMyType)が表示されます。

+3

私はこれを2回+1できたらいいですか?私は過去2年ほど前にそれを棄権しました。私は別のプロジェクトで再び同じ質問に戻ってきましたが、それがまさに私が必要としていたものであることがわかりました。素晴らしい答え、ありがとう! – Paccc

+0

すごくいいですが、FooEditorはどこにも使われていません。いくつかのプロパティのTypeEditorとして設定する必要があります。 – virious

+1

@virious型エディタは、プロパティまたは型に対して指定できます。この場合は '(FooEditor)、typeof(UITypeEditor))]')を使って 'Foo'型に適用されます。従って***型 'Foo'の全ての***プロパティは、デフォルトでこのエディタを使います。この例の 'MyType.Foo'を参照してください。 –

関連する問題