使用ReactiveUI WPF无法将Enum值列表从ViewModel绑定到视图中的组合框

时间:2019-06-26 18:04:23

标签: c# wpf reactiveui

让我们说我有这个枚举

 public enum LogType
     {
         None = 0,
         File = 1,
         Folder = 2
     }

我在视图中有这个组合框

    <ComboBox Name="CustomLogLogType"  FontSize="10"
              MinHeight="20" Height="20" SelectedItem="{Binding LogType}">

然后像这样的ViewModel

public class CustomLogRuleItemViewModel : ReactiveObject
{

    [Reactive]
    public LogType LogType { get; set; } = LogType.File;

    public List<LogType> LogTypes => Enum.GetValues(typeof(LogType)).Cast<LogType>().Where(_ => _ != LogType.None).ToList();
}

然后在后面的代码中查看

public partial class CustomLogRuleItemView : ReactiveUserControl<CustomLogRuleItemViewModel> 
{
    public CustomLogRuleItemView()
    {
        InitializeComponent();

        this.ViewModel = new CustomLogRuleItemViewModel();
        this.DataContext = this.ViewModel;

        //The below works
        //CustomLogLogType.ItemsSource = this.ViewModel.LogTypes;


        this.WhenActivated(
            disposables =>
            {

                //If I use below it will error with exception
                this.OneWayBind(this.ViewModel,
                        _ => _.LogTypes, _ => _.CustomLogLogType.ItemsSource)
                    .DisposeWith(disposables);
            });
    }
}

基本上,如果我在下面绑定,它会起作用

CustomLogLogType.ItemsSource = this.ViewModel.LogTypes;

但是,如果我尝试使用ReactiveUI进行如下所示的绑定

            this.OneWayBind(this.ViewModel,
                    _ => _.LogTypes, _ => _.CustomLogLogType.ItemsSource)
                .DisposeWith(disposables);

我得到一个异常,指出ReactiveUI.IViewFor上的LogType违反了类型“ T”的约束。不确定为什么要对IViewFor进行争论,因为这与View的ViewModel实现有关。

1 个答案:

答案 0 :(得分:1)

问题在于,默认情况下,ReactiveUI会通过解析ItemTemplate来设置IViewFor<TypeInItemsSource>,这意味着可以更轻松地拆分视图。因此,如果在这些情况下添加ItemTemplate,DisplayMemberPath或ItemTemplateSelector,则会关闭自动视图查找。请参阅enter image description here以获取执行此操作的代码行。

<ComboBox Name="CustomLogLogType"  FontSize="10"
                  MinHeight="20" Height="20">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>

我能够通过添加自己的ItemTemplate来解决它。

我认为这实际上是一个错误,因此,如果您不介意在this code处打开错误,我会在接下来的几天内对其进行修复。我认为对于原始类型我们不应该添加ItemTemplate,因为实际上我看不到用户实际上希望为原始类型使用此功能。