1

以前はデフォルトのコンストラクターを使用していた C# で作成したコンポーネントがありますが、それ自体への参照を渡すことによって、その親フォームに (デザイナーで) オブジェクトを作成させたいと考えています。

つまり、designer.cs の次の代わりに:

        this.componentInstance = new MyControls.MyComponent();

フォーム デザイナーに次の作成を指示したいと思います。

        this.componentInstance = new MyControls.MyComponent(this);

これを達成することは可能ですか (できれば属性/注釈などを介して)?

4

2 に答える 2

2

Control.Parentプロパティを単純に使用することはできませんか? 確かに、コントロールのコンストラクターでは設定されませんが、それを克服する一般的な方法は、ISupportInitializeを実装し、 EndInitメソッドで作業を行うことです。

所有しているコントロールへの参照が必要なのはなぜですか?

ここで、新しいコンソール アプリケーションを作成し、このコンテンツを貼り付けて Program.cs のコンテンツを置き換えて実行すると、.EndInitParentプロパティが正しく設定されていることがわかります。

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

namespace ConsoleApplication9
{
    public class Form1 : Form
    {
        private UserControl1 uc1;

        public Form1()
        {
            uc1 = new UserControl1();
            uc1.BeginInit();
            uc1.Location = new Point(8, 8);

            Controls.Add(uc1);

            uc1.EndInit();
        }
    }

    public class UserControl1 : UserControl, ISupportInitialize
    {
        public UserControl1()
        {
            Console.Out.WriteLine("Parent in constructor: " + Parent);
        }

        public void BeginInit()
        {
            Console.Out.WriteLine("Parent in BeginInit: " + Parent);
        }

        public void EndInit()
        {
            Console.Out.WriteLine("Parent in EndInit: " + Parent);
        }
    }

    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
    }
}
于 2009-06-01T21:28:28.313 に答える
0

デザイナにデフォルト以外のコンストラクタを呼び出すコードを実際に発行させる方法はわかりませんが、これを回避するためのアイデアを次に示します。初期化コードを親フォームの既定のコンストラクター内に配置し、Form.DesignMode を使用して実行する必要があるかどうかを確認します。

public class MyParent : Form
{
    object component;

    MyParent()
    {
        if (this.DesignMode)
        {
            this.component = new MyComponent(this);
        }
    }
}
于 2009-06-01T23:02:59.527 に答える