[] デザイナで配置できるコントロールを作ったらコンストラクタが2回呼ばれる

デザイナで配置できる自作コントロールを作ると、デザイナで配置した時と実行したとき、計2回コンストラクタが呼ばれることになるみたい。

DataGridViewを継承したコントロールを作ってみた場合。
デフォルトで列が2個追加されてるみたいなやつ。

using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    class MyDataGridView : DataGridView
    {
       public MyDataGridView()
            : base()
        {
            this.Columns.Add("col1", "列1");
            this.Columns.Add("col2", "列2");
        }
    }
}

ソリューションのビルドするとツールボックスに表示されてデザイナで配置できる状態になるので、配置。
配置時に既に勝手に列が2個ある。
uw000043.jpg

これをそのまま実行すると
uw000042.jpg

勝手に増えてる!

デザイナで配置するときだけ列を追加したい・・・配置時だけ動かしたい処理はInitLayout()をoverrideするといいみたい。
ヘルプには

継承時の注意 派生クラスで InitLayout をオーバーライドする場合は、基本クラスの InitLayout メソッドを呼び出して、コントロールが正しく表示されるようにしてください。

て書いてあるので、base.InitLayout()を忘れずに。

using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    class MyDataGridView : DataGridView
    {
       public MyDataGridView()
            : base()
        {
            // こっちをやめて
            //this.Columns.Add("col1", "列1");
            //this.Columns.Add("col2", "列2");
        }

       protected override void InitLayout()
       {
           // ベースのInitLayout
           base.InitLayout();

           // こっちに入れる
           this.Columns.Add("col1", "列1");
           this.Columns.Add("col2", "列2");

       }
    }
}

これでビルドして配置しなおせば
uw000044.jpg
増えなくなった。っていうメモ。

あ、でもデザイナでプロパティとか変更したりすると再度InitLayoutが呼ばれて列が増えちゃう。

protected override void InitLayout()
{
   // ベースのInitLayout
   base.InitLayout();

    // こっちに入れる 
    if(!this.Columns.Contains("col1"))
    this.Columns.Add("col1", "列1");
    if (!this.Columns.Contains("col2"))
    this.Columns.Add("col2", "列2");
}

こういう対応しておけば安心かな


[この記事はブログからの移行データです。元の記事]