首页 > 解决方案 > XAML 中使用 Lambda 表达式和 MVVM 模式的 OneWay/TwoWay 绑定

问题描述

我无法在使用带有表达式的模式时绑定Combobox.SelectedItemin 。XAMLViewModelMVVMlambda

在我的MainWindow.xaml我有:

<ComboBox ItemsSource="{Binding Products}" IsEnabled="{Binding ProductsIsEnabled}" SelectedItem="{Binding SelectedProduct}" />

在我MainWindow.xaml.csDataContext设置中(我的所有其他代码都xaml可以正常工作)。

在我的MainWindowViewModel.cs我有:

...
public string TitleText => Title.Text;
...
public ObservableCollection<object> Products => MyConverter.GetCollection(ProductList);
public bool ProductsIsEnabled => MyProduct.IsEnabled;
public object SelectedProduct => ProductList.SelectedItem; // --> this does not work
...

我在运行时收到的错误是

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Private.CoreLib.dll
A TwoWay or OneWayToSource binding cannot work on the read-only property 'SelectedProduct' of type 'MyNamespace.MainWindowViewModel'.

我所有的对象都实现了INotifyPropertyChanged. 有谁知道我在这里错过了什么或做错了什么?

提前致谢!

标签: c#xamlbinding

解决方案


public object SelectedProduct => ProductList.SelectedItem;是一个简短的形式

public object SelectedProduct
{
  get
  {
    return ProductList.SelectedItem;
  }
}

这意味着具有 lambda 表达式的属性是没有设置器的属性;它是一个只读属性。SelectedItem用户可以更改组合框的值,即用户可以更改SelectedProduct属性的值。

要修复它,您必须使用属性的设置器,或者您必须以两种方式更改绑定:

<ComboBox ItemsSource="{Binding Products}" IsEnabled="{Binding ProductsIsEnabled}" SelectedItem="{Binding SelectedProduct, Mode=OneWay}" />

单向绑定意味着如果用户更改该属性,该属性将保持不变。仅当您更改属性时,UI 元素才会更改。

附录:在我阅读了您的评论后:您的属性ProductList.SelectedItem可以有一个 getter 和一个 setter,但这并不意味着您的属性SelectedProduct将有一个 setter 和一个 getter。将其更改为

public object SelectedProduct
    {
      get
      {
        return ProductList.SelectedItem;
      }
      set
      {
        ProductList.SelectedItem = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedProduct)));
      }
    }

它应该可以工作。


推荐阅读