5

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

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

在此处输入图像描述

对象结构如下:

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 */
}

视图需要绑定到 MyObject,然后按其 Type 属性对 Objects 属性进行分组。

现在,我已经在不使用响应式扩展的情况下完成了这项工作,但感觉很糟糕......我想通过将 MyObject 的 Objects 属性转换为可观察的来实现这一点,理论上,它应该允许我在任何时候更新总和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 */
}

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

4

1 回答 1

7

您可以使用 ReactiveUI 的响应式集合,它提供了许多可观察对象,包括一个用于集合更改时 ( Changed) 和一个用于集合中的项目更改时 ( ItemChanged)。这可以与ObservableAsPropertyHelper相关属性结合使用。

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

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);

    }
}
于 2013-08-15T08:28:40.243 回答