Visual Studio 2010 自習書 ~ Do-It-Yourself シリーズ ~
|
コントロール | プロパティ | 値 |
textBox1 | Text | 0 |
VerticalContentAlignment | Center | |
button1 | Content | ▲ |
Button2 | Content | ▼ |
この結果、WPF デザイナーは次の図のようになります。
textBox1 の文字列をわかりやすくするためフォント サイズ (FontSize プロパティ) を大きくすることもできます (ただし、コントロールを配置したときに、配置場所のフォント サイズを反映しなくなります)。
続いて、コード ビハインド (NumericBox.xaml.cs) で、このユーザー コントロールの機能を割り当てます。ここには次のように記述してください。
public partial class NumericBox : UserControl
{
public int Value
{
get
{
int n;
if (int.TryParse(textBox1.Text, out n))
return n;
return 0;
}
set
{
textBox1.Text = value.ToString();
}
}
public NumericBox()
{
InitializeComponent();
}
}
ここでは、整数値をあらわす Value プロパティを定義しています。Value の値は、設定するときはテキスト ボックスの文字列として渡され、取得するときはテキスト ボックスに入力されている文字列を整数値に変換して返します。
さらに 2 つのボタンについて、次のように Click イベントのイベント ハンドラーを割り当てます。
private void button1_Click(object sender, RoutedEventArgs e)
{
Value = Value + 1;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Value = Value - 1;
}
これで、上下のボタンを使える数値入力用のコントロールが完成しました。[Shift] - [F6] などを押して、このプロジェクトをビルドしておいてください。
ページのトップへ
3. ユーザー コントロールの利用
最初に作成した WPF アプリケーション プロジェクトに戻ります。ソリューション エクスプローラーでプロジェクト名を右クリックし、[参照の追加] を選びます。ここで、「プロジェクト」タブを選ぶと、作成した MyControlLibrary ライブラリが表示されています (下図)。
[OK] ボタンを押すと、このプロジェクトからライブラリに登録されているコントロールを使えるようになります。ただし、WPF デザイナーで編集するときには、まだツール ボックスに追加したコントロールは表示されていません。このため、ツール ボックスを右クリックして、[アイテムの選択] を選びます。すると、アイテムの選択画面になるので、[WPF コンポーネント] タブを選び、[参照] ボタンを押します。ここで、先ほどビルドしておいたライブラリ (.dll) を指定します。
(図をクリックすると拡大図が表示されます)
すると、ツール ボックス アイテムの選択で、NumericBox コントロールが表示されてチェックされるので、[OK] ボタンを押します。
ツール ボックスに新しいコントロール (NumericBox) が表示されます。
これで、他のコントロールと同じように、ツール ボックスからドラッグ アンド ドロップして、コントロールを配置できるようになります。テスト用に NumericBox と Button コントロールを 1 つずつ配置し、Button の Click イベントに次のようなイベント ハンドラーを割り当てます。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Value = " + numericBox1.Value.ToString());
}
}
プログラムを実行した様子を次に示します。
なお、ここで作成したコントロールは、プログラムで Value プロパティを扱うことはできますが、第 5 回で学んだデータ バインディングの対象として使うことはできません。データ バインディングとして使えるプロパティは、「依存プロパティ」でなければならないためです。
依存プロパティを作成する (参考)
依存プロパティの実装は、単純なプロパティの実装よりも複雑になります。前述の NumericBox コントロールの Value プロパティを、依存プロパティとして実装する例を以下に示します。
public partial class NumericBox : UserControl
{
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
static void valueChangedCallBack(DependencyObject property,
DependencyPropertyChangedEventArgs args)
{
NumericBox searchTextBox = (NumericBox)property;
searchTextBox.textBox1.Text = args.NewValue.ToString();
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(NumericBox),
new FrameworkPropertyMetadata(0,
new PropertyChangedCallback(valueChangedCallBack)));
public NumericBox()
{
InitializeComponent();
textBox1.LostFocus += new RoutedEventHandler(textBox1_LostFocus);
}
void textBox1_LostFocus(object sender, RoutedEventArgs e)
{
int n;
if (int.TryParse(textBox1.Text, out n))
Value = n;
else
Value = 0;
}
……button1_Clickとbutton2_Click
}
ここで ValueProperty という依存プロパティを静的に定義していることに注意してください。ここに用意されたデータに基づいて、コントロールの外部から間接的にプロパティを変更できる仕組みが提供されています。また、ここでは Value プロパティと TextBox コントロールの Text プロパティが直接連動しないため、TextBox からフォーカスが失われたときに、Value プロパティを更新しています。TextBox にフォーカスがある間 (値を入力している間) は、Value プロパティが変化しない (バインディング対象に影響しない) ことに注意してください。
ページのトップへ
4. まとめ
最初に述べたとおり、既存のコントロールを組み合わせてユーザー コントロールを作成する以外にも、既存のコントロールを拡張してカスタム コントロールを作成する方法があります。これは、既存のコントロールの仕組み (プロパティやイベント) をあまり変更する必要がないものの、コントロール テンプレートのように外観の変更だけで済まない場合に便利です。
全 9 回を通じて学んだとおり、Visual Studio 2010 を活用することで、機能的かつ使いやすい Windows アプリケーションを容易に開発できます。ぜひ、皆さんもチャレンジしてみてください。
ページのトップへ