使用 ReactiveUI 从 ReactiveList 获取所选项目集合

Get Selected Items collection from a ReactiveList using ReactiveUI

我已经将 ReactiveList Orders 绑定到 wpf 中的数据网格。 我通过以下语法

成功获得了单个 selected 订单
private Order _selectedOrder;
public Order SelectedOrder
{
    get { return _selectedOrder; }
    set { this.RaiseAndSetIfChanged(ref _selectedOrder, value); }
}
this.WhenAnyValue(x => x.Orders.ItemChanged).Select(x => _selectedOrder = ((Order)x));

但是如果我在数据网格中添加多个 select 个订单,我如何获得 selected 项目?

你的代码似乎没有执行你想要的,因为你似乎在听 ReactiveList ItemChanged observable(当你的数据源改变时会触发),而你想看的是网格选择。

虽然未经测试,但以下代码似乎更符合您想要实现的目标(使用 reactiveui-events 助手):

// in the VM
public IList<Order> SelectedOrders { /* regular RxUI property as usual */ }

// in the view
this.Grid.Events().SelectionChanged
    .Select(_ => this.Grid.SelectedItems.Cast<Order>().ToList())
    .Subscribe(list => ViewModel.SelectedOrders = list);

我明白你想要实现的目标了吗?

根据 Gluck 给出的提示,我找到了一种通过在视图中为数据网格添加选择更改事件处理程序来获取选定订单集合的方法,如下所示

在 ViewModel 中添加一个反应式 属性

private IList<Order> selectedOrders;
public IList<Order> SelectedOrders
{
    get
    {
        return selectedOrders;
    }
    set { this.RaiseAndSetIfChanged(ref selectedOrders, value); }
}

并在视图的代码隐藏中

private void OrdersGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ViewModel.SelectedOrders = OrdersGrid.SelectedItems.Cast<Order>().ToList();
}

首先,您需要将 EventPattern 转换为 IObservable。您可以使用如下方式执行此操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Windows.Controls;

namespace System.Windows.Controls.Extensions
{
    public static class ListBoxExtensions
    {
        public static IObservable<List<T>> SelectionChanged<T>(this ListBox listBox)
        {
            return Observable.FromEventPattern<SelectionChangedEventHandler, SelectionChangedEventArgs>(
                eh => listBox.SelectionChanged += eh,
                eh => listBox.SelectionChanged -= eh)
                .Select(_ => listBox.SelectedItems.Cast<T>().ToList());
        }
    }
}

然后在您的 Control 中,将结果绑定到 ViewModel,如下所示:

    public partial class MyControl : UserControl, IViewFor<MyViewModel>
    {
        public MyControl()
        {
            InitializeComponent();

            this.WhenActivated(d =>
            {
                MyListView.SelectionChanged<MyItemViewModel>()
                    .Do(list => ViewModel.SelectedItems = list)
                    .SubscribeOn(RxApp.MainThreadScheduler)
                    .ObserveOn(RxApp.MainThreadScheduler)
                    .Subscribe()
                    .DisposeWith(d);
            });
        }

        object IViewFor.ViewModel
        {
            get => ViewModel;
            set => ViewModel = value as MyViewModel;
        }

        public MyViewModel ViewModel
        {
            get => DataContext as MyViewModel;
            set => DataContext = value;
        }
    }