如何将视图模型的ReactiveList绑定到包含视图模型的Views的ListView

时间:2016-10-27 04:39:51

标签: c# wpf xaml listview reactiveui

我的ParentViewModel包含ReactiveList ChildViewModels。我想将其绑定到显示ListView的{​​{1}}。 ChildViews将某些文字绑定到ChildView,并根据状态枚举设置Label资源:

ParentViewModel.cs Image

的简单容器
ChildViewModels

ChildViewModel.cs 有一些文字和public class ParentViewModel : ReactiveObject { public ReactiveList<ChildViewModel> Children { get; } = new ReactiveList<ChildViewModel>(); }

Status

ParentView.xaml public class ChildViewModel : ReactiveObject { public string SomeText { get; set; } public enum Status { Unknown, Known } public Status CurrentStatus { get; set; } = Status.Unknown; } 使用UserControl为数据模板打包ListView。我确保在ChildView上添加ViewModel="{Binding}"

DataTemplate

ParentView.xaml.cs 为其<UserControl x:Class="MyProject.UI.ParentView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:vm="clr-namespace:MyProject.View_Models" xmlns:ui="clr-namespace:MyProject.UI"> <ListView x:Name="ChildList" BorderThickness="0"> <ListView.ItemTemplate> <DataTemplate> <!--I have also tried the following line, didn't work --> <!--<DataTemplate DataType="{x:Type vm:ChildViewModel}">--> <ui:ChildView ViewModel="{Binding}"/> </DataTemplate> </ListView.ItemTemplate> </ListView> </UserControl> 创建依赖项属性,并将视图模型的ParentViewModel绑定到ChildList ListView

Children

ChildView.xaml 简单public partial class ParentView : UserControl, IViewFor<ParentViewModel> { public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register( "ViewModel", typeof(ParentViewModel), typeof(ParentView)); object IViewFor.ViewModel { get { return ViewModel; } set { ViewModel = (ParentViewModel)value; } } public ParentViewModel ViewModel { get { return (ParentViewModel )GetValue(ViewModelProperty); } set { SetValue(ViewModelProperty, value); BindToViewModel(value); } } private void BindToViewModel(ParentViewModel viewModel) { this.OneWayBind(viewModel, vm => vm.Children, v => v.ChildList.ItemsSource); } } UserControlImage

Label

ChildView.xaml.cs 绑定<UserControl x:Class="MyProject.UI.ChildView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel Orientation="Horizontal"> <Image Name="StatusIcon" Margin="2" /> <Label Name="DisplayName" /> </StackPanel> </UserControl> 并设置图片数据

ChildViewModel

我在public partial class ChildView : UserControl, IViewFor<ChildViewModel> { public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register( "ViewModel", typeof(ChildViewModel), typeof(ChildView)); public ChildView() { InitializeComponent(); } object IViewFor.ViewModel { get { return ViewModel; } set { ViewModel = (ChildViewModel)value; } } public ChildViewModel ViewModel { get { return (ChildViewModel )GetValue(ViewModelProperty); } set { SetValue(ViewModelProperty, value); BindToViewModel(value); } } private void BindToViewModel(ChildViewModel viewModel) { viewModel .WhenAnyValue(vm => vm.CurrentStatus) .Subscribe(status => { // set StatusIcon's image based on status }); this.Bind(viewModel, vm => vm.DisplayName, v => v.SomeText); } } 中设置了断点,以查看ViewModel属性是否命中,但它们永远不会。当我将ChildView添加到ChildViewModels时,会创建ParentVieWModel.Children,但它永远不会被正确绑定。我可以订阅ChildView的{​​{1}}事件并手动设置绑定,但我想以正确的XAML / ReactiveUI方式执行此操作。我错过了什么?

1 个答案:

答案 0 :(得分:0)

我认为您需要在ChildViewModel中完全设置属性,以便它们引发您的ChildView可以订阅的ViewModel中的更改。请参阅ViewModels documentation

string someText ;
public string SomeText {
    get { return someText; }
    set { this.RaiseAndSetIfChanged(ref someText , value); }
}

Status currentStatus;
public Status CurrentStatus {
    get { return currentStatus; }
    set { this.RaiseAndSetIfChanged(ref currentStatus, value); }
}

或者如果其中一个或两个都是只读的。

readonly ObservableAsPropertyHelper<string> someText;
public string SomeText{
    get { return someText.Value; }
}

readonly ObservableAsPropertyHelper<Status> currentStatus;
public Status CurrentStatus{
    get { return currentStatus.Value; }
}