http://d.hatena.ne.jp/pmoky/20061108

 言われる前に行っちゃうと、最後の例がUserControlではダメでControllerを使うべきものになっていない。驚きだ。なんてったって例が出てこなかったのだ。使うべきケースは絶対ある、それこそ無数にあるはずなんだけど、出てこなかった。不思議だ。なんにせよUserControlはよく出来てるんだなあ。

 UserControlにinterfaceを実装させて、Form上で組み合わせることで大概のことはこなせる。TrackBarに反応するControlを一般化することを考えてみる。TrackBarがスライドした時に、色が変わったり、値が変わったりいろいろするけど、そういうのを一般化してプログラミングする。

interface ISlide{
  //TrackBarがスライドした時に実行される
  void Slide(int val);
}

class Slider : UserControl{
  TrackBar tb;
  ISlide slide;

  //このプロパティはデザイナ上で選択できる。
  public ISlide SlideObj{
    get{ return slide; }
    set{ slide = value; }
  }

  tb_ValueChanged(...){
    slide.Slide(tb.Value);
  }
}

//Sliderの値を表示するだけのTextBox
class SliderValueTextBox : UserControl, ISlide{
  ...

  public void Slide(int val){
    textBox.Text = val.ToString();
  }
}

 Sliderの値を表示する、SliderValueTextBoxをFormに置くと、Sliderのビジュアルデザイナ上のSlideObjプロパティでそのコントロールが選択可能になる。恐ろしい機能だ。

 こうしてバラバラに分解できるなら、UserControlに複数のControlを配置すると位置関係が動かせなくなる、というデメリットを消せる。しかし複数のControlを協調動作させる時には複数を集約したUserControlが必要になって、そのせいで位置関係がうまく動かせなくなる、というシナリオを想定していたのだけど、甘かった。実に甘かった。例が出てこない。なぜだ。

 よっぽど複雑なケースにならないとダメなのかも知らぬ。ううむ。ないわけはないんだが。

 ボタンをクリックした時にもう一つのボタンがクリックできなくなる、という処理を再利用するとしよう。しかしそれも(あるボタンが押されるとクリックできなくなるボタン)というユーザーコントロールがあれば別に大丈夫だ。Form上ではただ組み立てるだけだ。プロパティをいじればいい。

 ダメだ。もしかするとUserControlじゃダメなケースなんてないのかもしれない。むむむ…。

 そうだ。モード変更する場合、たとえば、CheckBoxがチェックの時とチェックされていないときで他のコントロールの動作が変わる場合なんかはControllerが出てくる。そんなもんかなあ。