WPF/UWP:ラジオボタンの選択をコードから切り替えるには?[C#/VB]:.NET TIPS
WPFアプリ/UWPアプリで、コードビハインドからラジオボタンの選択状態を変更する方法を解説する。
対象:.NET 3.5以降、Visual Studio 2012以降
Windowsストアアプリ/Windows Phone 8.1/UWPアプリのXAMLでも利用可
UIコントロールの状態をコードビハインドから変えようとしたときに、少々厄介なのはラジオボタンだ。データバインディングが絡むと難しくなるのである。思い通りに動いてくれず、困ってしまったのは筆者だけではないはずだ。
本稿では、基本を確認する意味で、データバインディングを利用しない場合を解説する。ここでは難しい問題は何もない。データバインディングを利用するときの問題点と解決策は、別稿で述べる予定だ。なお、本稿のサンプルは「Windows desktop code samples:.NET Tips #1125」からダウンロードできる。
ラジオボタンの選択をコードから切り替えるには?
新しく選択状態にしたいラジオボタンのIsCheckedプロパティにtrueをセットすればよい*1。
それだけで、それまで選択状態だったラジオボタンは、自動的に非選択状態に戻るのだ。エンドユーザーがラジオボタンをクリックしたときと同じ動作をしてくれるのである。
*1 ラジオボタンコントロールにコードから直接アクセスすることが条件だ。IsCheckedプロパティにバインドしたデータソースを変更してもうまくいかない。詳細は別稿に譲るが、これが冒頭に述べた問題である。
実際に試してみよう。
次の図とコードのようなUIを考える。ラジオボタンに対応するボタンがあり、ボタンのクリックによってラジオボタンの選択を切り替えたいのである。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
……省略……
<StackPanel x:Name="RadioButtosGroup1" ……省略……>
……省略……
<RadioButton Tag="1">選択肢1</RadioButton>
<RadioButton Tag="2">選択肢2</RadioButton>
<RadioButton Tag="3">選択肢3</RadioButton>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1" ……省略……>
<Button Click="SelectButton_Click" Tag="1">1</Button>
<Button Click="SelectButton_Click" Tag="2">2</Button>
<Button Click="SelectButton_Click" Tag="3">3</Button>
</StackPanel>
……省略……
</Grid>
このコードは、Visual Studio 2012のWPFアプリと、Visual Studio 2015のUWPアプリで動作を確認している。
ラジオボタンを収めているスタックパネルに「RadioButtosGroup1」という名前を付けてある。次のコードで使うので、覚えておいてほしい。個々のラジオボタンに名前を付けていないのは、データテンプレートにラジオボタンを配置する場合も想定しているためである。
また、ラジオボタンとボタンに、対応するTagプロパティを設定してある。クリックされたボタンのTagプロパティを見れば、どのラジオボタンを選択状態にすればよいか分かるという仕掛けだ。
なお、別途公開のサンプルには、データバインディングを使うコードも入っている。参考にしてほしい。
クリックされたボタンに応じてラジオボタンの選択状態を切り替えるコードビハインドは、次のようになる。
このコードでは、対象のラジオボタンを見つけ出すために「Linq-to-XAML」を使っているので、本稿のコードを自分で実際に書いてみる場合にはプロジェクトに導入しておく必要がある(「.NET TIPS:WPF/UWP:Linq-to-XAMLで簡単にUIコントロールへアクセスするには?[C#/VB]」参照)。
public partial class MainWindow : Window
{
// ラジオボタンを保持するためのコレクション
List<RadioButton> _radioButtons;
public MainWindow()
{
InitializeComponent();
// ラジオボタンを取り出す(Linq-to-XAMLを利用)
_radioButtons = RadioButtosGroup1.Descendants()
.OfType<RadioButton>().ToList();
}
// ボタンのクリックイベントハンドラ
private void SelectButton_Click(object sender, RoutedEventArgs e)
{
string tag = (e.Source as Button).Tag as string;
SelectRudioButton(tag);
}
private void SelectRudioButton(string tag)
{
// 新しく選択状態にしたいラジオボタンのIsCheckedプロパティをtrueにする
_radioButtons.Where(rb => rb.Tag.Equals(tag)).First().IsChecked = true;
}
}
Class MainWindow
' ラジオボタンを保持するためのコレクション
Private _radioButtons As List(Of RadioButton)
Public Sub New()
' この呼び出しはデザイナーで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
' ラジオボタンを取り出す(Linq-to-XAMLを利用)
_radioButtons = RadioButtosGroup1.Descendants() _
.OfType(Of RadioButton)().ToList()
End Sub
' ボタンのクリックイベントハンドラ
Private Sub SelectButton_Click(sender As Object, e As RoutedEventArgs)
Dim tag As String = CType(CType(e.Source, Button).Tag, String)
SelectRudioButton(tag)
End Sub
Private Sub SelectRudioButton(tag As String)
' 新しく選択状態にしたいラジオボタンのIsCheckedプロパティをtrueにする
_radioButtons.Where(Function(rb) rb.Tag.Equals(tag)).First().IsChecked = True
End Sub
End Class
このコードは、Visual Studio 2012のWPFアプリで動作を確認している。
結局のところ、新しく選択状態にしたいラジオボタンのIsCheckedプロパティをtrueにしているだけである。ここではLINQを使ってラジオボタンのTagプロパティから目的のラジオボタンを見つけ出しているが、ラジオボタンに名前を付けてあるならその名前で直接アクセスしてもよい。
また、UWPアプリでもほぼ同様である(「e.Source」→「e.OriginalSource」といった修正が必要)。別途公開のサンプルにはUWP版も入っているので、参考にしてほしい。
なお、ラジオボタンのIsCheckedプロパティを双方向データバインディングしている場合でも、上のコードのようにしてラジオボタンの状態を変えるのは問題ない(ラジオボタンの状態が変われば、双方向バインディングによってバインディングソースにも反映される)。バインディングソースの変化をラジオボタンのIsCheckedプロパティに反映させようとすると、うまく動いてくれないのである。
まとめ
ラジオボタンの選択状態を切り替えるには、新しく選択状態にしたいラジオボタンのIsCheckedプロパティをコードビハインドからtrueにセットすればよい。
利用可能バージョン:.NET Framework 3.5以降
カテゴリ:WPF/XAML 処理対象:RadioButtonコントロール
使用ライブラリ:RadioButtonコントロール(System.Windows.Controls名前空間)
関連TIPS:WPF/UWP:Linq-to-XAMLで簡単にUIコントロールへアクセスするには?[C#/VB]
Copyright© Digital Advantage Corp. All Rights Reserved.