RadioButtonにCollectionを渡したい(C# WPF)

C#

RadioButtonを使いたいけど以下のようにべた書きすると、IsCheckedプロパティがViewModelに大量発生するので嫌ですよね。

<RadioButton Content="TestA" IsChecked="{Binding IsTestAChecked}"/>
<RadioButton Content="TestB" IsChecked="{Binding IsTestBChecked}"/>
<RadioButton Content="TestC" IsChecked="{Binding IsTestCChecked}"/>

MVVMにせず、コードビハインドならサクッと書けますが、MVVMでやろうとすると面倒です。
どういうやり方がいいかなぁと考えたのですが、ListBoxの見た目をRadioButtonにする方法が良い気がします。

<ListBox ItemsSource="{Binding TestList}" SelectedItem="{Binding SelectedItem}" SelectionMode="Single">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <RadioButton Content="{Binding}" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

実体はListBoxなのでItemsSourceにそのままCollectionを渡せます。
SelectedItem=”{Binding SelectedItem}”としているので、ViewModelのSelectedItemにItemを取り出せます。

注意ですが、SelectionMode=”Multiple”にはしないで下さい。
RadioButtonの見た目なだけで、グルーピングしていないので複数選択ができてしまい、ラジオボタンとして機能しません。
また、IsEnabled等のプロパティを設定した場合、Background等を任意に変更できません。
理由はBackground等の制御はListBoxのTemplateで行われているからで、これを弄るにはItemContainerStyleだけでなく、ListBoxのTemplateを修正する必要があります。

以下、失敗作

<ListBox.ItemTemplate>
    <DataTemplate>
        <RadioButton GroupName="ListRadioButton" Content="{Binding}" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}" />
    </DataTemplate>
</ListBox.ItemTemplate>

ItemTemplateを使うと見た目はそれっぽくなります。
GroupNameを使ってRadioButtonの制御も問題ないのですが、ListBoxのSelectedItemの取得ができません。

こんな感じでRadioButtonとListBoxのSelectが一致しません。

C#
スポンサーリンク
Once and Only

コメント