TIPS:WPF:ラジオボタンの選択をバインディングソースに反映させるには?[C#/VB]WPFアプリで双方向データバインディングを使用して、ラジオボタンの選択状態を反映する方法、その問題点と解決策を解説する。3.5以降UIコントロールの状態の変化をデータに反映させたい場合がある。そんなとき、XAMLでは双方向のデータバインディングを利用するのが便利だ。エンドユーザーがテキストボックスに入力した文字列は、データバインディングによってバインディングソースの文字列型プロパティに自動的に反映させられる。スライダーの「つまみ」の位置を浮動小数点数のプロパティに反映できる。その主な方法には2通りあるのだが、本稿では簡単な方を解説する。#1126」からダウンロードできる*1。本稿の内容はUWPアプリにも適用できる。後述するようにデータの変更をラジオボタンに反映できないという欠点がある。UWPアプリでは、データバインディングにコンバータを介する方法を使うべきである。そのため、UWPアプリについては本稿でも扱わないし、サンプルコードにも含めていない。ラジオボタンの選択をデータに反映させる2通りの方法RadioButtonコントロール(System.Windows.Controls名前空間)の選択状態は、真偽値型のIsCheckedプロパティで示される。三つの選択肢に対応した三つのラジオボタンがあるとする。そこには「三つの選択肢のどれが選択されているか」を表すプロパティは存在しない。あるのは、三つのIsCheckedプロパティだけなのだ。三つの状態を取り得る列挙型のデータとバインドしたくても、直接バインドすることはできない。そこで考えられる解決策の一つは、三つの選択肢に対応した三つ真偽値型プロパティをデータの側にも用意する方法だ。考え方は簡単ではあるが、データの変更をラジオボタンに反映させる方法に難があるという弱点がある。本稿では、この方法を解説する。4以降に限定されるが、データバインディングにコンバータを介する方法だ。こちらは別稿に譲りたい。例として、次のコードのようなデータを考えてみよう。三つの状態を取れる列挙型のプロパティを持っているクラスだ。Classデータを表す列挙体とクラス(上:C#、下:VB)「SampleData」クラスには、UIコントロールとデータバインディングするために、INotifyPropertyChangedインタフェース(System.ComponentModel名前空間)を実装してある。このデータをテキストブロックにバインドして「One」「Two」「Three」と表示するのは簡単だ。テキストブロックのTextプロパティにデータバインディングするだけである(次のコード)。/></StackPanel>データをバインドするテキストブロック(XAML)ここでは、スタックパネルの中にテキストブロックを配置した。このスタックパネルには、次のコードでデータコンテキストにデータを設定する。Sub「SampleData」インスタンスをデータバインディングする(上:C#、下:VB)ウィンドウのコンストラクタに、太字の部分を追加する。ラジオボタンの状態をデータバインディングしてみよう。前述したように、データの側にも三つの選択肢に対応した三つの真偽値型プロパティを用意すればよい(次のコード)。Classデータに真偽値型プロパティを三つ追加する(上:C#、下:VB)追加した三つのプロパティのうち、「Is1」プロパティのみを示す。同様にして、「Is2」「Is3」も実装する。太字で示したように、「Value」プロパティのセッターにもコードを追加する。コードの全体は、別途公開のサンプルをご覧いただきたい。次のコードのようにラジオボタンとバインドする。/>......省略......</StackPanel>データをバインドするラジオボタン(XAML)前述したテキストブロックと同じスタックパネル内に、ラジオボタンを三つ追加した。コードの全体は、別途公開のサンプルをご覧いただきたい。これで実行してみると次の画像のようになる。ラジオボタンの選択を変えるとデータに反映され、その値がデータバインディングでテキストブロックに表示されている。ラジオボタンの選択を変えるとデータに反映されるこの画像は、[選択肢2]のラジオボタンをクリックしたところ。その変化がバインドされている「SampleData」クラスに反映され、その結果として「SampleData」クラスをバインドしているテキストブロックの表示も「Two」に変化している。この方法の欠点この方法は簡単ではあるが、このままではデータの変更をラジオボタンに反映できない。画面にボタンを追加し、そのクリックイベントでデータを変更するようにしてみよう(次のコード)。Tag="3">3</Button></StackPanel></StackPanel>データ変更用のボタン(XAML)前述のコードに太字の部分を追加した。Subクリックされたボタンに応じてデータを変更する(上:C#、下:VB)ボタンのTagプロパティには「1」「2」「3」という数字が設定されている。ボタンクリックのイベントハンドラ(=このコード)で、Tagプロパティの値を「SampleEnum」列挙型に変換し、データバインドされている「SampleData」クラスの「Value」プロパティにセットする。これで、ボタンに応じた値にデータが変更されると、そのデータの変化がラジオボタンに反映されるはずなのだ(実際には、次に述べるような不具合が発生する)。実行してみると、次のような不具合が現れるはずだ。ボタンを[1]→[2]→[3]とクリックするだけでなく、[2]→[1]や[1]→[3]などと、しばらく操作を続けてみてほしい。4.0以降)問題の回避策この問題を回避するには、データを切り替えるときに、いったん範囲外の値にすればよい(次のコード)。Property不具合を回避するコード(上:C#、下:VB)「SampleData」クラスの「Value」プロパティのセッターに、太字の部分を追記する。これでデータの変更が正しくラジオボタンに反映されるようになる。いうものの、データの側でバインディング先のコントロールの都合を考慮するというのはおかしなものだ。上の回避策はバインディング先がラジオボタンだから必要なのであって、例えばチェックボックスならば不要なのだ。まとめラジオボタンの選択状態をデータに反映させるには、データバインディングを使う。簡易的には、ラジオボタンの選択状態に対応する真偽値のプロパティをデータのクラスに追加すればよい。この方法では逆にデータの変化をラジオボタンの選択状態に反映させようとすると、不具合の回避策が必要になる。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。