Jul
08
WPF RadioButton Binding to IsChecked Property
Warning: Please consider that this post is over 13 years old and the content may no longer be relevant.
I wasted a few development hours discovering this strange behaviour when binding to the IsChecked property of a RadioButton in WPF when using MVVM. You can read about the issue on the MSDN forum, but from my experience if you have a two way binding on the is IsChecked property of a RadioButton which is part of a group, then after you set the bound property in code a couple of times, the RadioButton loses it’s binding all together.
Here is my original code that kept losing it’s binding:
<ItemsControl ItemsSource="{Binding Elements}" Margin="0,10,0,10">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Key}"
GroupName="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Title}"
IsChecked="{Binding Path=IsSelected}"
Margin="0,5,0,5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
There a couple of ways to solve this,
- You can subclass the RadioButton
- You could use OneWay binding on IsChecked to set the RadioButton state from code, then bind the Command property to a Command when user clicks on the RadioButton.
<ItemsControl ItemsSource="{Binding Elements}" Margin="0,10,0,10">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Key}"
GroupName="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Title}"
IsChecked="{Binding Path=IsSelected, Mode=OneWay}"
Command="{Binding IsSelectedCommand}"
CommandParameter="{Binding}"
Margin="0,5,0,5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
- My preferred option: (as suggested by karliwatson) use a ListBox for the grouping and bind the ListBoxItem’s IsSelected property to your ViewModel, then bind the RadioButton’s IsChecked property to the list box item’s IsSelected property. Don’t set a group on the RadioButton.
<ListBox ItemsSource="{Binding Elements}" Margin="0,10,0,10" BorderThickness="0" Background="Transparent">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Key}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
Margin="0,5,0,5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>