Using the accepted answer, I crafted this converter to bind multiple checkboxes to a [Flags]Enum
. Note: this converter uses a class member, so do not reuse the same converter instance for multiple sets of bindings.
XAML:
<StackPanel>
<StackPanel.Resources>
<local:EnumFlagConverter x:Key="myConverter" />
</StackPanel.Resources>
<CheckBox Content="Option1" IsChecked="{Binding TheEnum, Converter={StaticResource myConverter}, ConverterParameter={x:Static local:MyEnum.Option1}}" />
<CheckBox Content="Option2" IsChecked="{Binding TheEnum, Converter={StaticResource myConverter}, ConverterParameter={x:Static local:MyEnum.Option2}}" />
<CheckBox Content="Option3" IsChecked="{Binding TheEnum, Converter={StaticResource myConverter}, ConverterParameter={x:Static local:MyEnum.Option3}}" />
</StackPanel>
C#:
public class EnumFlagConverter : IValueConverter
{
public Enum CurrentValue { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var theEnum = value as Enum;
CurrentValue = theEnum;
return theEnum.HasFlag(parameter as Enum);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var theEnum = parameter as Enum;
if ((bool)value)
CurrentValue = CurrentValue.Or(theEnum);
else
CurrentValue = CurrentValue.And(theEnum.Not());
return CurrentValue;
}
}
public static class Extensions
{
public static Enum Or(this Enum a, Enum b)
{
// consider adding argument validation here
if (Enum.GetUnderlyingType(a.GetType()) != typeof(ulong))
return (Enum)Enum.ToObject(a.GetType(), Convert.ToInt64(a) | Convert.ToInt64(b));
else
return (Enum)Enum.ToObject(a.GetType(), Convert.ToUInt64(a) | Convert.ToUInt64(b));
}
public static Enum And(this Enum a, Enum b)
{
// consider adding argument validation here
if (Enum.GetUnderlyingType(a.GetType()) != typeof(ulong))
return (Enum)Enum.ToObject(a.GetType(), Convert.ToInt64(a) & Convert.ToInt64(b));
else
return (Enum)Enum.ToObject(a.GetType(), Convert.ToUInt64(a) & Convert.ToUInt64(b));
}
public static Enum Not(this Enum a)
{
// consider adding argument validation here
return (Enum)Enum.ToObject(a.GetType(), ~Convert.ToInt64(a));
}
}