UWP ListView 将 SelectedItem 绑定到视图模型中的 属性

UWP ListView bind SelectedItem to property in viewmodel

我正在尝试将 ListView 中的 SelectedItem 绑定到视图模型中的 属性 SelectedSection。我收到以下错误: "Invalid binding path 'ViewModel.SelectedSection' : Cannot bind type 'Model.Section' to 'System.Object' without a converter"。我目前正在将 ListView 的 ItemSource 绑定到 CurrentProject 属性 中的列表。我尝试制作一个转换器,但我不太确定我应该如何转换以及转换什么。当我试图获取我需要使用 SelectedValue 和 SelectedValuePath 的 属性 时,我遇到了同样的错误。

<ListView Name="SectionsListView"
                IsItemClickEnabled="True"
                ItemsSource="{x:Bind ViewModel.CurrentProject.Sections, Mode=OneWay}"
                SelectedItem="{x:Bind ViewModel.SelectedSection, Mode=TwoWay}">

视图模型:

 private Section selectedSection = new Section();
 public Section SelectedSection
 {
     get { return selectedSection; }
     set { selectedSection = value; OnPropertyChanged(nameof(SelectedSection)); }
 }

 private Project currentProject;
 public Project CurrentProject
 {
     get { return currentProject; }
     set { currentProject = value; OnPropertyChanged(nameof(CurrentProject)); }
 }

转换器:

 public object Convert(object value, Type targetType, object parameter, string language)
 {
     return value;
 }
 public object ConvertBack(object value, Type targetType, object parameter, string language)
 {
     return value as Section;
 }

如果您使用传统的 {Bindings } 标记实现此功能,则不会出现此问题,因为绑定是在运行时评估的,而 { x:Bind } 在编译时求值。

这里的情况是 ItemsSource 和 SelectedItem 都是 Object 类型的属性,因此当您的 Target 尝试更新 Source 时会出现问题,因为您无法分配 属性 类型对象到您的 (ViewModel.SelectedSection) 属性. 相反不会引发任何错误,因为您可以将 ViewModel.SelectedSection 属性 隐式转换为对象。

x:Bind 的一个特点是您可以转换您的属性,例如:

{x:Bind (x:Boolean)CheckBox.IsChecked, Mode=TwoWay}"

问题在于,由于在您的情况下我们没有处理 XAML 内部数据类型之一,因此您必须将 ViewModel class 映射到 XAML 命名空间,通过将它包含在页面根目录下定义的 XML 命名空间中。

xmlns:myviewmodel="using:......"

包含它之后,我认为您可以成功地将它转换为所需的引用类型,而不会出现任何编译错误,方法如下:

<ListView Name="SectionsListView"
                IsItemClickEnabled="True"
                ItemsSource="{x:Bind ViewModel.CurrentProject.Sections, Mode=OneWay}"
                SelectedItem="{x:Bind (myviewmodel:ViewModel) ViewModel.SelectedSection, Mode=TwoWay}">

或者您可以对代码进行一些调整并使用 {Binding },老实说,这完全简化了这个过程!

感谢您的回复,我通过将数据上下文设置为视图模型并改用常规绑定来使其正常工作。

<ListView Name="SectionsListView"
          DataContext="{x:Bind ViewModel}"
          ItemsSource="{Binding CurrentProject.Sections, Mode=OneWay}"
          SelectedItem="{Binding SelectedSection, Mode=TwoWay}">