While looking at solutions for tying an enum to a group of RadioButtons, I discovered Sam's post from a year and a half ago.
Lars' answer was exactly what I was looking for: simple and effective.
Until I started changing the object tied to the RadioButton group. A simple version follows.
The XAML:
<Window x:Class="RadioEnum.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:re="clr-namespace:RadioEnum"
Height="200" Width="150">
<Window.DataContext>
<re:ViewModel />
</Window.DataContext>
<Window.Resources>
<re:EnumBooleanConverter x:Key="enumBooleanConverter" />
</Window.Resources>
<DockPanel>
<ComboBox DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Things}" DisplayMemberPath="Name" />
<GroupBox>
<StackPanel>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=First}">First</RadioButton>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Second}">Second</RadioButton>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Third}">Third</RadioButton>
</StackPanel>
</GroupBox>
</DockPanel>
</Window>
Now, the C#:
namespace RadioEnum
{
public class ViewModel {
public ObservableCollection<Thing> Things { get; set; }
public ViewModel() {
Things = new ObservableCollection<Thing> {
new Thing{ Name = "Thing1", Choice = Choice.First, },
new Thing{ Name = "Thing2", Choice = Choice.Second, },
};
}
}
public class Thing {
public string Name { get; set; }
public Choice Choice { get; set; }
}
public enum Choice { None, First, Second, Third, }
public class EnumBooleanConverter : IValueConverter {
// Yes, there are slight differences here from Lars' code, but that
// was to ease debugging. The original version has the same symptom.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
object ret = DependencyProperty.UnsetValue;
var parameterString = parameter as string;
if (parameterString != null && Enum.IsDefined(value.GetType(), value)) {
object parameterValue = Enum.Parse(value.GetType(), parameterString);
ret = parameterValue.Equals(value);
}
return ret;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
object ret = DependencyProperty.UnsetValue;
var parameterString = parameter as string;
if (parameterString != null && !value.Equals(false))
ret = Enum.Parse(targetType, parameterString);
return ret;
}
}
}
When the application loads with Thing1 in the ComboBox, the correct Choice is selected in the radio group. Selecting Thing2 from the ComboBox correctly updates the Choice. But, from this point, switching no longer updates the binding to the Second RadioButton and thus no longer calls the Convert method with parameter set to "Second".
In other words, although Thing2's values have not changed, all of the RadioButtons are cleared from that point forward. Thing1 continues to work, though.
There are no errors seen - neither exceptions nor messages in the Output window. I've tried binding in different ways. I tried making Choice a DependencyProperty, too (and Thing then a DependencyObject).
Any insights out there?