1

プロパティをカスタマイズしようとしています。楕円ボタン[...]をクリックすると、新しいダイアログフォームが表示されます。残念ながら、フォームは表示されません。以下のコードを確認して、どこが間違っていたのかアドバイスしていただけますか?

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

namespace Test01
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }


        void MainFormLoad(object sender, EventArgs e)
        {
            Form form = new Form();

            propertyGrid1.SelectedObject = new MyType();

        }
    }

    class MyType
    {
        private string bar;

        [Editor(typeof(FooEditor), typeof(UITypeEditor))]
        [TypeConverter(typeof(ExpandableObjectConverter))]
        public string Bar
        {
            get { return bar; }
            set { bar = value; }
        }
    }

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

1 に答える 1

3

エディターはFooタイプで動作しますが(そうvalueでない場合はFooダイアログは表示されません)、のインスタンスを作成すると、タイプのMyTypeプロパティが1つ含まれているため、で編集することはできません。BarstringFooEditor

コードがどのように機能するかを試すには、プロパティBarをからstringに変更する必要がありFooます。

class MyType
{
    private Foo bar = new Foo();

    [Editor(typeof(FooEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public Foo Bar
    {
        get { return bar; }
        set { bar = value; }
    }
}


2つの例を見てみましょう。最初の例では、Attributeが適用されたプロパティを編集します(次に、エディターがプロパティ自体の値を変更します)。

これはで編集するクラスです。この例では役に立たないためPropertyGrid、クラスを削除しました。Foo

class MyType
{
    private string bar;

    [Editor(typeof(MyStringEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public string Bar
    {
        get { return bar; }
        set { bar = value; }
    }
}

Barこれは、プロパティを編集するエディターです。実際には、次のタイプの任意のプロパティで機能しますstring

class MyStringEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        string text = value as string;
        if (svc != null && text != null)
        {
            using (FooForm form = new FooForm())
            {
                form.Value = text;
                if (svc.ShowDialog(form) == DialogResult.OK)
                {
                    return form.Value;
                }
            }
        }

        return value;
    }
}

別の例として、エディターはプロパティ値自体を変更せず、そのプロパティのプロパティの値を変更します(エディターはMyType.Bar(タイプのFoo)プロパティに適用されますが、のプロパティの値を変更しValueますFoo

Barプロパティの複合型をもう一度紹介しましょう。

class Foo
{
    private string _value;
    private object _tag; // Unused in this example

    public string Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public object Tag
    {
        get { return _tag; }
        set { _value = _tag; }
    }
}

クラスを変更して、作成した複合型の1つのプロパティを公開します。現在、その型に固有の新しいエディターを使用しているMyTypeことに注意してください。EditorAttributeFoo

class MyType
{
    private Foo bar = new Foo();

    [Editor(typeof(FooEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public Foo Bar
    {
        get { return bar; }
        set { bar = value; }
    }
}

Foo最後に、タイプのエディターを作成します。このエディタはプロパティの値のみを変更し、Foo.Valueによって公開されている他のプロパティは変更されFooないことに注意してください。

class FooEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        Foo foo = value as Foo;
        if (svc != null && foo != null)
        {
            using (FooForm form = new FooForm())
            {
                form.Value = foo.Value;
                if (svc.ShowDialog(form) == DialogResult.OK)
                {
                    // Updates the value of the property Value
                    // of the property we're editing. 
                    foo.Value = form.Value;
                }
            }
        }

        // In this case we simply return the original property
        // value, the property itself hasn't been changed because
        // we updated the value of an inner property
        return value;
    }
}

最後の注意:のifブロックでsvc.ShowDialog()は、からの更新値がありForm、プロパティBar(エディターが適用される場所)は変更されませんが、それに含まれるインスタンスのValueプロパティを更新します。Foo次のようなものを書くのとほぼ同じです。

MyType myType = new MyType();
myType.Bar.Value = form.Value;

(前の例のように)プロパティの新しい値を返すだけの場合、プロパティの古い値はTag失われます。次のようになります。

MyType myType = new MyType();
Foo foo = new Foo();
foo.Value = form.Value;
myType.Bar = foo;

違いがわかりますか?とにかく、それは答えよりもチュートリアルになりすぎるでしょう...

例はテストされていないことに注意してください。ここに書いたばかりです。確かに機能する例を提供するだけでなく、概念を公開したいと思います。

参考文献

ここでは、役立つリソースの短いリストを見つけることができます。

于 2013-02-28T10:07:34.233 に答える