自定义 INotifyPropertyChanged 行为 Linq to SQL

Custom INotifyPropertyChanged Behavior Linq to SQL

关于我几年前的这个 post 半: C# WPF DataGridTextColumn custom property

我需要进行一些更改,以便在其他字段更改时更新我的​​数据网格中的总数。这意味着我的解决方法(编辑按钮)消失了,所以我试图通过实现 INotifyPropertyChanged(我刚刚设置查看主键)。
我用这个作为参考: 如果我可以更改自动生成的 class 中 PaySum_Total getter 的行为,我就可以完成这项工作:

        public decimal PaySum_Total_Pay
        {
            get
            {
                return this._PaySum_Total_Pay;
            }
            set
            {
                if ((this._PaySum_Total_Pay != value))
                {
                    this.OnPaySum_Total_PayChanging(value);
                    this.SendPropertyChanging();
                    this._PaySum_Total_Pay = value;
                    this.SendPropertyChanged("PaySum_Total_Pay");
                    this.OnPaySum_Total_PayChanged();
                }
            }

对此:

        public decimal PaySum_Total_Pay
        {
            get
            {
                return this.CalcTotalOnChange();
            }
            set
            {
                //same code here from earlier
            }
        }

当然,一旦我对 dbml 进行任何更改,它就会被删除。我在另一个文件中创建了另一个部分 class 以在此处为 class 中的某些存根方法提供代码:

public partial class Payroll_SummaryReview : INotifyPropertyChanging, INotifyPropertyChanged
    {     
        partial void OnPaySum_Total_AdditionsChanged()
        {
            this.OnPaySum_Total_PayChanged();
        }
        partial void OnPaySum_Total_PayChanged()
        {
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_IsApprovedChanged()
        {
            //do something as approved cb changes...?
        }
        //partial void OnPaySum_Reason_DescriptionChanged();
        partial void OnPaySum_MinApprovedChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_TrainerChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_OOTChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_MiscAdditionsChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_PayCorrectionChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_CallInLoadPayChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }
        partial void OnPaySum_CallInPayChanged()
        {
            CalcTotalOnChange();
            this.SendPropertyChanged("PaySum_Total_Pay");
        }


        private decimal CalcTotalOnChange()
        {
            decimal total = 0m;

            decimal minimum = this.PaySum_Shifts ?? 0 * this.Min_Rate;
            bool minOk = (this.PaySum_Total_Extra_Pay ?? 0) + this.PaySum_Total_Load_Pay + (this.PaySum_MiscAdditions ?? 0) < minimum
                && this.PaySum_MinApproved
                && (this.PaySum_Total_Additions == null || this.PaySum_Total_Additions == 0);

            if (minOk) //misc addition inclucisive of minimums.
                this.PaySum_Total_Additions = minimum - (this.PaySum_Total_Extra_Pay ?? 0 + this.PaySum_Total_Load_Pay + this.PaySum_MiscAdditions ?? 0);
            else
                this.PaySum_Total_Additions = 0M;
            total = this.PaySum_Total_Extra_Pay ?? 0+
                this.PaySum_Total_Load_Pay +
                this.PaySum_Total_Additions ?? 0 +
                this.PaySum_OOT ?? 0 +
                this.PaySum_Trainer ?? 0 +
                this.PaySum_PayCorrection ?? 0 +
                this.PaySum_MiscAdditions ?? 0 +
                this.PaySum_CallInLoadPay ?? 0;
            int intMo = this.PaySum_Week_End_Date.Month;
            decimal callInRate = 0M;
            if (intMo > 3 && intMo < 10)
                callInRate = 100M;
            else
                callInRate = 85M;
            total += (Convert.ToDecimal(this.PaySum_CallInPay) * callInRate);

            //section determines eligibility for and amount of Seniority pay.... but I actually added this to the view so screw this section Payroll_SummaryReview.
            //Need to add source to source control
            this.PaySum_Seniority = total * this.SeniorityPercent ?? 0;

            return = total + this._PaySum_Seniority;
            //PayrollDataContext.SavedSummary = false; //need to set unsaved changes flag in Review somewhow
        }

由于 Linq 生成 属性 的方式,我似乎无法覆盖 public 十进制 PaySum_Total_Pay。还有其他我不知道的东西可以使这项工作吗?我也很乐意从不同的角度来处理这个问题,但我不确定现在的角度是什么,但我希望能在这里得到一些帮助。

抱歉,如果这有点乱七八糟的代码,但仍然是一个 WIP。

您可以在处理 PropertyChanged 事件的部分 non-autogenrated class 中实现默认构造函数或方法(我假设 auto-generated SendPropertyChanged 方法引发),然后在事件处理程序中更新并引发 PaySum_Total_PayPropertyChanged 事件。像这样:

public partial class Payroll_SummaryReview
{
    public Payroll_SummaryReview()
    {
        this.PropertyChanged += Payroll_SummaryReview_PropertyChanged;
    }

    private void Payroll_SummaryReview_PropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName != nameof(PaySum_Total_Pay))
        {
            this._PaySum_Total_Pay = ...;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(PaySum_Total_Pay)));
        }
    }
}