Windowsフォームデザイナーでツールボックスからカスタムコントロールを追加する場合の注意点

Visual Studio Community 2013で、C#で、Windows Formsでアプリ書いているんだが、なかなかやっかいなはまり方することが多くて困る。

今日はListViewを、継承してカスタムしたクラスに置き換えようとしてはまった。

カスタムコントロールを作るまでは、MSDNに書いてある感じでまあ問題ない。

方法 : 既存の Windows フォーム コントロールから継承する

問題はこのカスタムコントロールを、フォームデザイナーを使って、ツールボックスから追加しようとした場合に起きる。

上記の手順で追加した場合、カスタムコントロールはWindowsフォーム本体と同じ名前空間に属する。それ自体は自然だし問題ない。

だがフォームデザイナーがどうも、コントロールとフォーム本体が同じ名前空間に属する場合を想定していないようで、おかしなコードを出力する。

namespace MyApp
{
    partial class MyApp
    {
        ...

        private void InitializeComponent()
        {
            this.listView1 = new MyApp.ListView();

            ...
        }

        ...
    }
}

このコードが生成される、 myapp.designer.cs ファイルの名前空間MyApp になっているので、コンパイラMyApp.MyApp.ListView を見ようとしてエラーになる。

型名 'ListView' は型 'MyApp.MyApp' に存在しません。

対策としては、手動で書き換えるしかなさそうだ……。

今は大丈夫だけど、これからコントロールが増えてきたらどうしよう。

  • フォームデザイナーなんて使わず、手動で書く。
  • WPFに移行する。

どっちがいいだろうかね。困った。

おまけ

カスタムコントロールの方のクラスはまあこんな感じになるわけだが、

namespace MyApp
{
    public partial class ListView : System.Windows.Forms.ListView
    {
        public ListView()
        {
            InitializeComponent();
        }
    }
}

間違ってこう書くと、名前が被ってエラーになる。

using System.Windows.Forms;

namespace MyApp
{
    public partial class ListView : ListView
    {
        public ListView()
        {
            InitializeComponent();
        }
    }
}
'MyApp.ListView' と 'MyApp.ListView' を含む、循環する基本クラスの依存関係です。

まあ、ちゃんと文法わかってればない間違えなんだけど。

追記。

どうも、フォームデザイナーで修正する度に書き換えられちゃう模様。本気でどうにかしないと……。