添加和显示从实体计算并自动更新的元素

Add and Display an Element that is Calculated from entities and Automatically Updates

感谢您的帮助,很高兴随着答案和评论的出现更新和编辑这个问题。代码已经缩短,希望更容易阅读。

我正在尝试首先使用 Entity Framework 6 数据库在 WPF 中实现 MVVM。

我目前可以在数据网格中根据需要检索数据、执行 CRUD 和显示各个列。我的视图模型实现了 INotifyPropertyChanged 和 ICommand。

来自数据库的(简化的)实体模型是:

public Weight
    {
        public decimal Benchmark_Weight { get; set; }
        public decimal Security_Weight { get; set; }
    }

以及包含在视图模型中的模型的 public 属性:

public ObservableCollection<Weight> Weights
        {
            get;
            private set;
        }

然后我在视图模型的构造函数中实例化 entity framework 实例以检索数据并设置为本地权重。

public WeightsViewModel()
        {
            _context = new BenchMarkEntities();
            _context.Weights.Load();
            this.Weights = _context.Weights.Local;
         }

总的来说,我想显示额外的、自动更新的、根据实体模型中的每一行计算的数据。基本上,Active_Weight = Security_Weight - Benchmark_Weight.

因此,例如,我有一个数据网格,其中包含模型中的实体,然后在同一个数据网格、另一个数据网格或什至任何将显示计算数据集合的项目控件中,它会在我更新时自动更新数据网格中的 Security_Weight 或 Benchmark_Weight。

我最初能够通过两个不同的进程检索和显示计算的数据。

第一个过程是向实体模型添加部分 class:

public partial class Weight
    {
        public decimal ActiveWeight
        {
            get { return Security_Weight - Benchmark_Weight; }
        }
    }

然后在视图中绑定到这个属性。

另一个进程是:

0.5) 我不更改实体模型。 1)创建一个从实体模型中检索数据的方法:

ObservableCollection<decimal> Retrieve()
{
    ObservableCollection<decimal> temp = new ObservableCollection<decimal>();
    foreach (var item in Weights)
    {
        temp.Add(item.Security_Weight - item.Benchmark_Weight);
    }
    return temp;
}

2) 在viewmodel的构造函数中调用:

 public WeightsViewModel()
        {
            _context = new BenchMarkEntities();
            _context.Weights.Load();
            this.Weights = _context.Weights.Local;
            ActWeight2 = Retrieve();
        }

3) 分配给视图模型中的附加属性:

public ObservableCollection<decimal> ActWeight2
        {
            get;
            set;
        }

但我可以看出第二个过程存在缺陷,因为如果调用 Retrieve,您将添加更多项目。

这是 XAML:

UpdateSourceTrigger=PropertyChanged}"
              AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="SecurityWeight" Binding="{Binding Security_Weight}"/>
                <DataGridTextColumn Header="BenchmarkWeight" Binding="{Binding Benchmark_Weight}"/>
                <DataGridTextColumn Header="ActiveWeight" Binding="{Binding ActiveWeight}"/>
            </DataGrid.Columns>

    </DataGrid>
        <ListBox ItemsSource="{Binding ActWeight2}"/>

问题:当我进行更新时,计算的数据不会在显示屏上更新。

任何有关如何执行此操作的指导将不胜感激。

黑麦

我认为最简单的方法是为 Weight 创建一个视图模型,然后在此视图模型上实现 INotifyPropertyChanged。然后,包含 ObservableCollection 的视图模型包含一个视图模型列表。您的 XAML 保持不变。这将允许 INPC 流向您的视图而不会阻塞您的模型 class.

包含 "list" 个权重的视图模型。

public class WeightsListViewModel : INotifyPropertyChanged
{
    public ObservableCollection<WeightViewModel> Weights
    {
        get;
        private set;
    }

    public WeightsListViewModel()
    {
        _context = new BenchMarkEntities();
        .Load();
        this.Weights = _context.Weights.Select(w => new WeightViewModel(w));
    }
}

包含单个权重的视图模型。

public class WeightViewModel : INotifyPropertyChanged
{
    public decimal Benchmark_Weight 
    { 
        get{ return _weight.Benchmark_Weight; } 
        set
        { 
            _weight.Benchmark_Weight = value;
            OnPropertyChanged("Benchmark_Weight");
            OnPropertyChanged("ActiveWeight");
        }
    }

    public decimal Security_Weight 
    { 
        get{ return _weight.Security_Weight; } 
        set
        { 
            _weight.Security_Weight = value;
            OnPropertyChanged("Security_Weight");
            OnPropertyChanged("ActiveWeight");
        }
    }

    public decimal ActiveWeight
    {
        get { return Security_Weight - Benchmark_Weight; }
    }

    private Weight _weight;
    public WeightViewModel(Weight weight){ _weight = weight; }
}