Reactive Extensions/Reactive UI观察集合,对其进行分组并显示它

Rob*_*etz 4 c# wpf system.reactive reactiveui

我有一个特定的数据集,需要存储分组和排序的数据.然后每一行都需要能够在任何单个项目发生变化时重新计算它的总和.

这是最终结果的基本外观:

在此输入图像描述

对象结构如下:

public class MyObject : INotifyPropertyChanged
{
  public ObservableCollection<MySubObject> Objects { get; set; }
  public Decimal TotalOfAll { get; set; }

  /* Ommited INPC and other properties for brevity */
}

public class MySubObject : INotifyPropertyChanged
{
  public Decimal Value { get; set; }
  public String RowType { get; set; }

  /* Ommited INPC and other properties for brevity */
}
Run Code Online (Sandbox Code Playgroud)

视图需要绑定到MyObject,然后通过它的Type属性对Objects属性进行分组.

现在,我已经完成了这个而没有使用反应式扩展,但它感觉很乱...我想通过将MyObject的Objects属性转换为一个observable来实现这一点,理论上,它应该允许我更新总和MySubObject的Value属性发生了变化.

我已经有了构建内容的视图方面,所以这不是问题......它已经完成了RX部分.

注意:

我也可以这样公开我的数据:

public class MyObject : INotifyPropertyChanged
{
  public ObservableCollection<MyRowObject> Objects { get; set; }
  public Decimal TotalOfAll { get; set; }

  /* Ommited INPC and other properties for brevity */
}

public class MyRowObject : INotifyPropertyChanged
{
  public ObservableCollection<MySubObject> Objects { get; set; }
  public String RowType { get; set; }
  public Decimal RowTotal { get; set; }

  /* Ommited INPC and other properties for brevity */
}

public class MySubObject : INotifyPropertyChanged
{
  public Decimal Value { get; set; }

  /* Ommited INPC and other properties for brevity */
}
Run Code Online (Sandbox Code Playgroud)

这将解决分组问题,但我仍然无法使其工作

Dan*_*eal 7

您可以使用ReactiveUI的反应式集合,它提供了许多可观察的集合,包括一个用于Changed集合change(ItemChanged)的时间,另一个用于集合中的项目更改()时.这可以与ObservableAsPropertyHelper依赖属性组合使用.

totalOfAll依赖性属性是非常简单的.另一个依赖属性 - groupedObjects- 有点复杂.我不确定我是否完全理解你的分组要求.希望下面的代码将成为一个起点 - 它将子对象的集合投影到一个IEnumerable匿名对象中,每个对象包含一个总计,一个行标题和项目.您应该能够在视图中绑定到此

public class MyObject : ReactiveObject
{
    public ReactiveCollection<MySubObject> Objects { get; set; }

    private ObservableAsPropertyHelper<IEnumerable<object>> groupedObjectsHelper;
    public IEnumerable<object> GroupedObjects
    { 
        get {return groupedObjectsHelper.Value;}
    }

    private ObservableAsPropertyHelper<Decimal> totalOfAllHelper;
    public Decimal TotalOfAll 
    {
        get {return totalOfAllHelper.Value;}
    }

    public MyObject()
    {
         var whenObjectsChange=
           Observable.Merge(Objects.Changed.Select(_ => Unit.Default),
                            Objects.ItemChanged.Select(_ => Unit.Default));

         totalOfAllHelper=
           whenObjectsChange.Select(_=>Objects.Sum(o => o.Value))
                            .ToProperty(this, t => t.TotalOfAll);

         groupedObjectsHelper=
           whenObjectsChange.Select(_=>Objects
                              .GroupBy(o => o.RowType)
                              .Select(g => new {RowType=g.Key,
                                                RowTotal=g.Sum(o => o.Value),
                                                Objects=g}))
                            .ToProperty(this, t => t.GroupedObjects);

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的 - 你是对的,我刚刚检查了github,它看起来像ReactiveCollection在ReactiveUI 5中变成了ReactiveList.我在mo只限于.Net 4.0,所以不幸的是不能使用最新的ReactiveUI并且没有注意到这个变化. (2认同)