计算的DataGrid列未更新,源是实体

时间:2014-11-05 07:26:38

标签: c# wpf entity-framework datagrid

这是对这个问题的跟进:

Entity Datagrid : best way to add computed values?

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

数据来源是自动生成的实体。因此,在完成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绑定到我添加的addtional属性。

  <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. 我需要添加并实现INotifyPropertyChanged BenchMarkEntities课程?

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

  3. 或者我需要将PropertyChanged事件及其方法添加到MainWindow吗?

    任何帮助或建议?

    谢谢

2 个答案:

答案 0 :(得分:0)

确保您关注此事:

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

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

答案 1 :(得分:0)

对于将通知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  
        }
  }

  //.....
}

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

Based on the discussion here您需要将模板中的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#>");
            }
        }
    }

<#+
}