Используя ReactiveUI
, я создал следующее альтернативное решение. Это не элегантное решение «все в одном», но, по крайней мере, оно читаемо.
В моем случае привязка списка enum
к элементу управления является редким случаем, поэтому мне не нужно масштабировать решение по базе кода. Однако код можно сделать более общим, изменив EffectStyleLookup.Item
на Object
. Я проверил это с моим кодом, никаких других изменений не требуется. Это означает, что один вспомогательный класс может быть применен к любому списку enum
. Хотя это уменьшило бы его читабельность - у ReactiveList<EnumLookupHelper>
нет большого звонка.
Использование следующего вспомогательного класса:
public class EffectStyleLookup
{
public EffectStyle Item { get; set; }
public string Display { get; set; }
}
В ViewModel преобразуйте список перечислений и выставьте его как свойство:
public ViewModel : ReactiveObject
{
private ReactiveList<EffectStyleLookup> _effectStyles;
public ReactiveList<EffectStyleLookup> EffectStyles
{
get { return _effectStyles; }
set { this.RaiseAndSetIfChanged(ref _effectStyles, value); }
}
// See below for more on this
private EffectStyle _selectedEffectStyle;
public EffectStyle SelectedEffectStyle
{
get { return _selectedEffectStyle; }
set { this.RaiseAndSetIfChanged(ref _selectedEffectStyle, value); }
}
public ViewModel()
{
// Convert a list of enums into a ReactiveList
var list = (IList<EffectStyle>)Enum.GetValues(typeof(EffectStyle))
.Select( x => new EffectStyleLookup() {
Item = x,
Display = x.ToString()
});
EffectStyles = new ReactiveList<EffectStyle>( list );
}
}
В ComboBox
используйте свойство SelectedValuePath
, чтобы привязать к исходному значению enum
:
<ComboBox Name="EffectStyle" DisplayMemberPath="Display" SelectedValuePath="Item" />
В представлении это позволяет нам привязать исходный enum
к SelectedEffectStyle
в ViewModel, но отобразить значение ToString()
в ComboBox
:
this.WhenActivated( d =>
{
d( this.OneWayBind(ViewModel, vm => vm.EffectStyles, v => v.EffectStyle.ItemsSource) );
d( this.Bind(ViewModel, vm => vm.SelectedEffectStyle, v => v.EffectStyle.SelectedValue) );
});