3

我在一些自定义实体中有主从关系。假设我有以下结构:

class Master : INotifyPropertyChanged
{
    public int Id { get; set; } // + property changed implementation 
    public string Name { get; set; } // + property changed implementation

    public ObservableCollection<Detail> Details { get; }
}

class Detail : INotifyPropertyChanged
{
     public int Id { get; private set; }
     public string Description { get; set; }
     public double Value { get; set; } // + property changed implementation
}

我的目标是拥有一个使用 GridView 的 ListView,显示 Master 对象的列表。当我选择一个特定的 Master 时,我将有一个单独的 ListView 用于详细信息,允许进行编辑。基本上,一个相当标准的主从视图。

但是,我还希望大师的 GridView 显示所有该大师的 Detail 元素的总和,即: Details.Select(d => d.Value).Sum();

使用自定义 IValueConverter 很容易显示。我可以从详细信息集合直接转换为双显示总和,并通过 IValueConverter 将 TextBlock 的文本绑定到 Details OneWay。这将起作用,并在我打开窗口时显示正确的值。

但是,如果我更改其中一个详细信息成员,这将不会更新(即使详细信息实现了 INotifyPropertyChanged),因为集合本身仍然是相同的(ObservableCollection 引用没有更改)。

我想在主列表中有一个聚合值,在详细列表中显示总和(或平均值/计数/等),并在用户更改详细属性时保持最新。我该如何实施呢?


编辑:

理想情况下,如果有一种不涉及直接更改 Master 类的方法来实现这一点,我会更喜欢。有问题的应用程序使用 MVVM 模式,我真的不希望更改我的模型类来实现特定的视图。有没有办法在不将自定义逻辑引入模型的情况下做到这一点?

4

1 回答 1

3

我正在考虑 UI 的可能性,您可以在其中显式绑定并从命令执行绑定/更新......但似乎最简单的方法是扩展 ObservableCollection 以向每个 Detail 添加/删除侦听器实例作为添加/删除,然后在其中任何一个更改时触发 CollectionChanged。称之为DeeplyObservableCollection<T>。

class Master : INotifyPropertyChanged
{
    public int Id { get; set; } // + property changed implementation 
    public string Name { get; set; } // + property changed implementation
    public double Sum {get {return Details.Sum(x=>x.Value);}}

    public DeeplyObservableCollection<Detail> Details { get; }

    // hooked up in the constructor
    void OnDOCChanged(object sender, CollectionChangedEventArgs e) 
    { OnPropertyChanged("Sum"); }
}

最坏的情况是,如果您无法正确覆盖所需的所有方法,则必须将 ObservableCollection 包装在另一种类型中......

于 2009-10-14T19:32:19.607 回答