wpf - 使用Reactiveui订购可观察的集合

标签 wpf mvvm prism reactiveui

我在订购ViewModel中的可观察集合时遇到一些困难。
这是我的情况:

在我的 View 模型中,我有以下列表:

public List<TicketModel> Tickets
        {
            get { return _Tickets.Value; }
            set
            {
                {
                    this.RaiseAndSetIfChanged(c => c.Tickets, value);
                }
            }
        }
        private ObservableAsPropertyHelper<List<TicketModel>> _Tickets;

此列表使用ReactiveAsyncCommand填充:
LoadTickets.RegisterAsyncFunction(x => loadTickets())
                .ToProperty(this, x => x.Tickets);

到目前为止所有作品。

我有另一个命令SortByCommand,只要用户想对集合进行排序就可以调用它。该命令如下所示:
SortByCommand = new ReactiveCommand(this.WhenAny(c => c.Tickets, ((tickets) => tickets.Value != null && tickets.Value.Count > 0)));
SortByCommand.Subscribe(c => sortTickets((SortByModel)c));

该命令还调用使用order by子句对集合进行排序的函数:
private void sortTickets(SortByModel model)
{
    Tickets = Tickets.OrderBy(model.Selector).ToList();
}

每当调用sortTickets函数时,都会引发一个异常,该异常表示:
Unable to cast object of type 'ReactiveUI.ObservableAsPropertyHelper`1[System.Collections.Generic.List`1[Bugmine.Modules.MyPage.Models.TicketModel]]' to type 'System.Collections.Generic.List`1[Bugmine.Modules.MyPage.Models.TicketModel]'.

我有几个问题:

1)为什么我不能直接设置Tickets模型?我是否需要首先将OrderBy的结果转换为某种可观察的集合?

2)有更好的方法吗?

编辑:澄清

我现在采用的方法是:
  • 每隔x秒重置Tickets集合一次。
  • 一旦调用sortTickets函数,我将通过以下方式对该集合进行排序和重置:
    Tickets = Tickets.OrderBy(c => c.Name).ToList(); //for example
  • 当再次加载Tickets集合时,我将检查是否应该对其进行排序,并在设置Tickets属性之前对其进行排序。

  • 这有点琐,因为我基本上将集合设置为两点-加载时和排序时。此外,加载后,我正在使用ReactiveUI帮助器-> ToProperty:
    LoadTickets.RegisterAsyncFunction(x => loadTickets())
        .ToProperty(this, x => x.Tickets);
    

    而排序后,我自己这样做:
    Tickets = Tickets.OrderBy(model.Selector).ToList();
    

    我想知道是否有更好的方法使用加载时已经使用的ReactiveUI方法进行排序。

    提前致谢!

    最佳答案

    解决此问题的另一种方法是通过CreateDerivedCollection:

    SortedTickets = Tickets.CreateDerivedCollection(
        x => new TicketViewModel(x),
        orderer: (l,r) => SortModel.Selector(l, r),  // Returns CompareTo() result
        signalReset: this.WhenAny(x => x.SortModel, x => x.Value));  // Reorder on SortModel change
    

    请注意,如果Tickets反复设置为(在本例中为),则此操作会失败-您可以将模型更改为在ctor中初始化Tickets,然后清除并添加所有项目,即
    LoadTickets.RegisterAsyncFunction(x => loadTickets())
        .Subscribe(x => {
            // TODO: Make sure Tickets is a ReactiveCollection
            Tickets.Clear();
            Tickets.AddRange(x);   // Will trigger resorting of SortedTickets
        });
    

    关于wpf - 使用Reactiveui订购可观察的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14556508/

    相关文章:

    wpf - 获取用于 Prism 导航的已注册 View 列表

    c# - Prism MVVM - 将 subview 添加到父 View 而不使用区域和注入(inject),只需 XAML

    c# - RichTextBox 中的 TextRange 构造函数性能

    c# - 使用 WebBrowser-Control 在 WPF 中显示本地 PDF 文件

    wpf - 具有可编辑集合的 MVVM 示例,其中 View 不直接使用模型类型

    wpf ContentPresenter 不会启用/禁用

    c# - 如何解决 "Could not load file or assembly ' Microsoft.Practices.Prism'“错误?

    c# - WPF问题: Need to draw a control on top of another

    wpf - 将 Textbox IsFocused 绑定(bind)到 Popup IsOpen 以及附加条件

    wpf - 将 WPF 设计数据与 MVVM 模式一起使用