Связывание OneWay / TwoWay в XAML с использованием лямбда-выражения и шаблона MVVM - PullRequest
0 голосов
/ 17 января 2020

Я не могу связать Combobox.SelectedItem in XAML в моем ViewModel, используя шаблон MVVM с lambda выражениями.

В моем MainWindow.xaml у меня есть:

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

В моем MainWindow.xaml.cs у меня правильно установлен DataContext (все остальные части моего кода в 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. Кто-нибудь знает, что я здесь упускаю или делаю неправильно?

Заранее спасибо!

1 Ответ

0 голосов
/ 17 января 2020

public object SelectedProduct => ProductList.SelectedItem; - это краткая форма для

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

Это означает, что свойство с лямбда-выражением является свойством без установщика; это свойство только для чтения. SelectedItem поля со списком может быть изменено пользователем, это означает, что пользователь может изменить значение свойства SelectedProduct.

Чтобы исправить это, вы должны будете либо установить на установщик значение свойство или вам придется изменить привязку двумя одним способом:

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

One-Way-Binding означает, что свойство остается неизменным, если пользователь изменяет его. Только если вы измените свойство, элемент пользовательского интерфейса изменится.

Приложение: После того, как я прочитал ваш комментарий: Ваше свойство ProductList.SelectedItem может иметь геттер и сеттер, но из этого это не означает, что ваше свойство SelectedProduct будет иметь сеттер и геттер. Измените его на

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

, и оно должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...