如何使用基于其他行计算的行实现DatagGrid的View Model

时间:2015-02-28 11:55:06

标签: c# wpf mvvm datagrid mvvm-light

我正在开发一个基于WPF DataGrid Control和MVVM设计模式的财务应用程序。在这个应用程序中,我需要DataGrid来显示基于其他行计算的行。在下图中,Unite Price,Quantity,Service Charges和Tax是数据行。用户可以像往常一样使用就地编辑来编辑这些行的值。但是其他行(计算行)是只读的,并根据给定的数据行和自定义表达式的值动态计算。例如,“Total”的自定义表达式将类似于[Unite Price] * [Quantity]。用户可以使用自己的自定义表达式添加新的计算行。

Sample of DataGrid

我对表达引擎有一些清晰的想法。但我在想这个场景中应该如何实现View Model。特别地,当用户更改数据行中的某些先前值时,视图模型应足够智能以更新计算值而不刷新整个DataGrid。目前,我已将数据行和计算行放在同一个Observable Collection中。但真正的问题是视图模型如何在必要时促进数据行和计算行之间的通信,以使计算值保持最新。

任何好的建议,有关此问题的建议或类似实施的源代码的链接都将非常感激

1 个答案:

答案 0 :(得分:0)

您可以为记录创建基类或接口,并实现它的两个版本:数据持有者和数据摘要。 Model是一个实现INotifyPropertyChanged的简单类。 ModelSummary派生自Model并具有计算属性。此外,它还必须收听Models PropertyChange事件。为简单起见,我重写了虚拟属性:

public class ModelSummary : Model
{
    private IEnumerable<Model> models;
    public ModelSummary(IEnumerable<Model> models)
    {
        this.models = models;
        foreach (Model model in models)
        {
            model.PropertyChanged += (s, e) => OnPropertyChanged(e.PropertyName);
        }
    }

    public override int Value1
    {
        get
        {
            return models.Sum(m => m.Value1);
        }
    }
}

ViewModel中的用法:

var list = new List<Model>
{
    new Model {Value1 = 1, Description = "A"},
    new Model {Value1 = 1, Description = "B"}
};

Values = new ObservableCollection<Model>(list)
{
     new ModelSummary(list) { Description = "Summary" }
};

我没有考虑添加新记录的可能性。