【问题标题】:Calculated Properties using Partial Classes(WPF)使用部分类 (WPF) 计算的属性
【发布时间】:2013-01-13 18:11:23
【问题描述】:

我正在尝试使用计算的列在我的网格中显示。

我有一个由 EF 代码生成器自动生成的部分类,具有三个属性:

这是我由 EF 实体生成器生成的代码

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;

namespace Employees.Contract
{
[DataContract(IsReference = true)]
[KnownType(typeof(Department))]
[KnownType(typeof(PropertyType))]
public partial class Employee: IObjectWithChangeTracker, INotifyPropertyChanged,IDataErrorInfo
{

    [NonSerialized]
    private CLOS.Contract.Validation.DataErrorInfoSupport dataErrorInfoSupport;

    public Employee()
    {            
        dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
        Init();
    }

    partial void Init();

    string IDataErrorInfo.Error { get { return dataErrorInfoSupport.Error; } }

    string IDataErrorInfo.this[string memberName] { get { return dataErrorInfoSupport[memberName]; } }

    #region Primitive Properties


    [DataMember]
    public Nullable<decimal> Salary
    {
        get { return _salary; }
        set
        {
            if (_salary != value)
            {
                _salary = value;
                OnPropertyChanged("Salary");
            }
        }
    }
    private Nullable<decimal> _salary;

    [DataMember]
    public Nullable<decimal> WageRate
    {
        get { return _wageRate; }
        set
        {
            if (_wageRate != value)
            {
                _wageRate = value;
                OnPropertyChanged("WageRate");
            }
        }
    }
    private Nullable<decimal> _wageRate;

    [DataMember]
    public Nullable<decimal> Bonus
    {
        get { return _bonus; }
        set
        {
            if (_bonus != value)
            {
                _bonus = value;
                OnPropertyChanged("Bonus");
            }
        }
    }
    private Nullable<decimal> _bonus;

    #endregion
    #region Navigation Properties

    [DataMember]
    public Department Department
    {
        get { return _department; }
        set
        {
            if (!ReferenceEquals(_department, value))
            {
                var previousValue = _department;
                _department = value;
                OnNavigationPropertyChanged("Department");
            }
        }
    }
    private Borrower _department;

    [DataMember]
    public PropertyType PropertyType
    {
        get { return _propertyType; }
        set
        {
            if (!ReferenceEquals(_propertyType, value))
            {
                var previousValue = _propertyType;
                _propertyType = value;

                OnNavigationPropertyChanged("PropertyType");
            }
        }
    }
    private PropertyType _propertyType;

    #endregion
    #region ChangeTracking

    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted)
        {
            ChangeTracker.State = ObjectState.Modified;
        }
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected virtual void OnNavigationPropertyChanged(String propertyName)
    {
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged{ add { _propertyChanged += value; } remove { _propertyChanged -= value; } }
    private event PropertyChangedEventHandler _propertyChanged;
    private ObjectChangeTracker _changeTracker;

    [DataMember]
    public ObjectChangeTracker ChangeTracker
    {
        get
        {
            if (_changeTracker == null)
            {
                _changeTracker = new ObjectChangeTracker();
                _changeTracker.ObjectStateChanging += HandleObjectStateChanging;
            }
            return _changeTracker;
        }
        set
        {
            if(_changeTracker != null)
            {
                _changeTracker.ObjectStateChanging -= HandleObjectStateChanging;
            }
            _changeTracker = value;
            if(_changeTracker != null)
            {
                _changeTracker.ObjectStateChanging += HandleObjectStateChanging;
            }
        }
    }

    private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e)
    {
        if (e.NewState == ObjectState.Deleted)
        {
            ClearNavigationProperties();
        }
    }

    protected bool IsDeserializing { get; private set; }

    [OnDeserializing]
    public void OnDeserializingMethod(StreamingContext context)
    {
        IsDeserializing = true;
    }

    [OnDeserialized]
    public void OnDeserializedMethod(StreamingContext context)
    {
        dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
        IsDeserializing = false;
        ChangeTracker.ChangeTrackingEnabled = true;
    }

    protected virtual void ClearNavigationProperties()
    {
        Department = null;
        PropertyType = null;
    }

    #endregion
}

}

如果我将OnPropertyChanged("Salary") 放入 EF Generated 类中的 Hours,Wage,Overtime 属性(这不是一个好主意),它也可以工作,因为如果类重新生成,我的代码将被清除

感谢任何帮助。 (对不起格式,这是我的第一个问题)

谢谢

【问题讨论】:

  • 您可以尝试让类处理它自己的PropertyChanged 事件并使用该处理程序调用OnPropertyChanged("Salary")
  • 您能否详细说明一下我的部分类(由 EF 生成的类)已经有 PropertyChanged 事件。任何示例代码都会有所帮助。原谅我的无知..

标签: wpf entity-framework wpfdatagrid partial-classes calculated-columns


【解决方案1】:

最终草案

(由于不相关,我删除了旧的编辑)

在你的部分类中添加,除了你对薪水的定义:

partial void Init()
{
    _propertyChanged += NotifySalary;
}

private void NotifySalary(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Wages" || e.PropertyName == "Hours" || e.PropertyName == "Overtime")
    {
        OnPropertyChanged("Salary");
    }
}

【讨论】:

  • 当我尝试创建构造函数时,它给了我以下错误类型'Employee'已经定义了一个名为'Employee'的成员,具有相同的参数类型
  • @pappu 我害怕那个。似乎 EF 正在自动生成一个构造函数。希望它是一个空的。请参阅编辑下方的 cmets。
  • 从您的回答看来,我必须修改自动生成的类才能实现我不想要的并且我正在使用 C# 的操作,还有其他想法吗?
  • 选项 D:不要使用 EF 生成的类。在 C# 中,无法链接成员声明中的事件。您必须在方法体或构造函数中执行此操作。每次创建Employee 的实例时是否要调用另一个方法?
  • 我注意到 EF Generated classes public Employee() { dataErrorInfoSupport = new Validation.DataErrorInfoSupport(this); 中的这个构造函数定义在里面();其中 Init 是一个 Partial 方法,我创建了相同的 Initi Partial 方法。部分无效 Init() { ((INotifyPropertyChanged)this).PropertyChanged += NotifySalary; }。但只要工资小时等值发生变化,它就不会触发 Property Changed 事件。
【解决方案2】:

我能够解决这个问题。发生的事情是服务将数据封送回 UI,但它没有用属性封送事件,所以我必须做的是从 UI 调用 init 方法并开始工作。

【讨论】:

    猜你喜欢
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2018-08-16
    相关资源
    最近更新 更多