计算数据网格列未更新,源为实体

本文关键字:实体 更新 数据 数据网 网格 计算 | 更新日期: 2023-09-27 18:29:22

这是这个问题的后续:

实体数据网格:添加计算值的最佳方式?

简而言之,我希望数据网格中的一列显示网格中其他两列的差异。当我在其他列中输入值时,我希望计算列的值能够更新。

数据的来源是一个自动生成的实体。因此,在完成ADO.NET实体模型过程之后,访问数据库的顶级类是:

public partial class BenchMarkEntities : DbContext
    {
        public BenchMarkEntities()
            : base("name=BenchMarkEntities")
        {            }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
        public virtual DbSet<BenchmarkDescription> BenchmarkDescriptions { get; set; }
        public virtual DbSet<SecurityDescription> SecurityDescriptions { get; set; }
        public virtual DbSet<Weight> Weights { get; set; }

以下是DbSet集合中包含的一个示例类:

using System;
using System.Collections.ObjectModel;
public partial class Weight
{
    public int BenchmarkID { get; set; }
    public string Symbol { get; set; }
    public decimal Benchmark_Weight { get; set; }
    public decimal Security_Weight { get; set; }
    public string Symbol_and_BenchmarkID { get; set; }
    public bool Weight_Exists { get; set; }
    public virtual BenchmarkDescription BenchmarkDescription { get; set; }
    public virtual SecurityDescription SecurityDescription { get; set; }
}

在MainWindow中,我必须实例化BenchmarkEntities才能对数据库执行CRUD操作。下面的代码来自教程。如果你有更好的方法,我很乐意看到它。

public partial class MainWindow : Window
{
    private BenchMarkEntities _context = new BenchMarkEntities();
    public MainWindow()
    {
        InitializeComponent();
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        System.Windows.Data.CollectionViewSource weightViewSource =
          ((System.Windows.Data.CollectionViewSource)(this.FindResource("weightViewSource")));
        _context.Weights.Load();
        // Load data by setting the CollectionViewSource.Source property:
        weightViewSource.Source = _context.Weights.Local;
    }

因此,正如另一个问题所建议的那样,我向类添加了一个属性(在本例中为Weight)。当我运行它时,我会得到一个正确的初始值。但是,当我在其他列中输入值时,计算的列不会更新。

public partial class Weight : INotifyPropertyChanged
{
    public Weight()
    {
        this.PropertyChanged += ActiveWeightPropertyChanged;
    }
    void ActiveWeightPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case "Benchmark_Weight":
            case "Security_Weight":
                OnPropertyChanged("DiffValues");
                break;
        }
    }
    public decimal DiffValues
    {
        get
        {
            return Benchmark_Weight - Security_Weight;
        }
    }
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(
                this, new PropertyChangedEventArgs(propName));
    }
    #endregion
}

}

这是我的XAML,第二个DataGridTextColumn绑定到我添加的addional属性。

  <DataGrid x:Name="weightDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Margin="51,21,54,99" 
                  ItemsSource="{Binding}" EnableRowVirtualization="True" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="benchmark_WeightColumn" Width="SizeToHeader" 
                                    Header="Benchmark Weight" Binding="{Binding Benchmark_Weight}"/>
                <DataGridTextColumn x:Name="ActiveWeightColumn" Width="SizeToHeader" Header="ActiveWeight"
                                    Binding="{Binding DiffValues}"/>
                <DataGridTextColumn x:Name="security_WeightColumn" Width="SizeToHeader" Header="Security Weight" Binding="{Binding Security_Weight}"/>
                <DataGridTextColumn x:Name="symbolColumn" Width="SizeToHeader" Header="Symbol" Binding="{Binding Symbol}"/>
                <DataGridCheckBoxColumn x:Name="Weigh_ExistsColumn" Header="Remove" IsThreeState="False" Binding="{Binding Weight_Exists}"/>
            </DataGrid.Columns>
        </DataGrid>

我想我知道该做什么,但不确定它是否可行。

  1. 我需要添加并实现INotifyPropertyChangedBenchMarkEntities类?

  2. 然后我需要更改两个属性的setter通知DiffValues。问题是这些都是自动生成的。

还是我需要将PropertyChanged事件及其方法添加到MainWindow?

有什么帮助或建议吗?

谢谢

计算数据网格列未更新,源为实体

确保您遵循以下内容:

    public partial class MyEntity : INotifyPropertyChanged
    {
        // Methods
    }
    public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<MyEntity> _listEntities = new ObservableCollection<MyEntity>();
        public ObservableCollection<MyEntity> ListEntities
        {
            get { return this._listEntities; }
            set { /* code here... */}
        }
    }

在这种情况下,您将把网格绑定到MyViewModel实例的ListEntities。此外,请尝试将绑定模式设置为TwoWay

您需要为两个将通知DiffValues的属性raisepropertychanged,类似于:

public partial class Weight: INotifyPropertyChanged
{
  //.....
  decimal  _benchmarkweight;
  decimal  _securityweight;
  public decimal Benchmark_Weight 
  {
     get{return _benchmarkweight;}
     set{
         _benchmarkweight=value; 
         OnPropertyChanged("Benchmark_Weight ");  
         // OnPropertyChanged("DiffValues");   //don't need if you raise it already in this.PropertyChanged 
        }
  }
  public decimal Security_Weight
  {
     get{return _securityweight;}
     set{
         _securityweight=value; 
         OnPropertyChanged("Security_Weight");  
        // OnPropertyChanged("DiffValues");  //don't need if you raise it already in this.PropertyChanged  
        }
  }
  //.....
}

编辑:很抱歉没有意识到这是实体:

根据这里的讨论,您需要将模板中的WriteProperty方法更改为以下方法,以便它将使用OnPropertyChanged:生成属性

void WriteProperty(string accessibility, string type, string name, string getterAccessibility, string setterAccessibility)
{
#>
    private <#=type#> _<#=name#>;
    <#=accessibility#> <#=type#> <#=name#> 
    { 
        <#=getterAccessibility#>get
        {
            return _<#=name#>;
        } 
        <#=setterAccessibility#>set
        {
            if (value != _<#=name#>)
            {
                _<#=name#> = value;
                OnPropertyChanged("<#=name#>");
            }
        }
    }
<#+
}