Насколько я знаю, нет хорошего способа сделать это с MultiBinding
, хотя вы изначально думаете, что будет. Поскольку вы не можете связать ConverterParameter
, ваша реализация ConvertBack
не имеет необходимой информации.
Я создал отдельный класс EnumModel
исключительно для привязки перечисления к переключателям. Используйте конвертер для свойства ItemsSource
, и тогда вы привязываетесь к EnumModel
. EnumModel
- это просто объект пересылки, который делает возможным связывание. Он содержит одно возможное значение перечисления и ссылку на модель представления, поэтому он может преобразовать свойство модели представления в логическое значение и обратно.
Вот непроверенная, но общая версия:
<ItemsControl ItemsSource="{Binding Converter={StaticResource theConverter} ConverterParameter="SomeEnumProperty"}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton IsChecked="{Binding IsChecked}">
<TextBlock Text="{Binding Name}" />
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Конвертер:
public class ToEnumModelsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var viewmodel = value;
var prop = viewmodel.GetType().GetProperty(parameter as string);
List<EnumModel> enumModels = new List<EnumModel>();
foreach(var enumValue in Enum.GetValues(prop.PropertyType))
{
var enumModel = new EnumModel(enumValue, viewmodel, prop);
enumModels.Add(enumModel);
}
return enumModels;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Модель Enum:
public class EnumModel : INPC
{
object enumValue;
INotifyPropertyChanged viewmodel;
PropertyInfo property;
public EnumModel(object enumValue, object viewmodel, PropertyInfo property)
{
this.enumValue = enumValue;
this.viewmodel = viewmodel as INotifyPropertyChanged;
this.property = property;
this.viewmodel.PropertyChanged += new PropertyChangedEventHandler(viewmodel_PropertyChanged);
}
void viewmodel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == property.Name)
{
OnPropertyChanged("IsChecked");
}
}
public bool IsChecked
{
get
{
return property.GetValue(viewmodel, null).Equals(enumValue);
}
set
{
if (value)
{
property.SetValue(viewmodel, enumValue, null);
}
}
}
}
Для примера кода, который, как мне известно, работает (но он все еще довольно неполированный - WIP!), Вы можете увидеть http://code.google.com/p/pdx/source/browse/trunk/PDX/PDX/Toolkit/EnumControl.xaml.cs. Это работает только в контексте моей библиотеки, но демонстрирует установку имени EnumModel на основе DescriptionAttribute
, который может быть полезен для вас.