-1

Semi-regarding this post of mine from several years ago: C# WPF DataGridTextColumn custom property

summary screen

I've needed to make some changes so that the total in my datagrid updates when other fields change. This means my workaround (the edit button) goes away, so I am trying to make some modifications to the partial linq to sql class for a view that I use for calculations by implementing INotifyPropertyChanged (I just set the view primary key).
I'm using this as a reference: Calculated column in datagrid WPF I can make this work if I can change the behavior of the PaySum_Total getter in the auto generated class from this:

        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();
                }
            }

to this:

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

but of course this gets removed as soon as I make any changes to the dbml. I have created another partial class in another file to provide code for some of the stub methods in the class here:

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
        }

It looks like I can't override the public decimal PaySum_Total_Pay because of the way Linq generates the property. Is there something else I'm not aware of to make this work? I also would be more than happy to approach this from a different angle but I'm not sure what that angle would be right now, but I would appreciate some help here.

Sorry if this is rambling a bit and ugly code, but still a WIP.

  • Is `SendPropertyChanged` auto-generated? – mm8 Mar 02 '22 at 14:18
  • Yes`protected virtual void SendPropertyChanged(String propertyName) { if ((this.PropertyChanged != null)) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }` – Jeremiah Halstead Mar 02 '22 at 14:26
  • Then you should be able to handle the event and raise a new event for the total property. See my answer. – mm8 Mar 02 '22 at 14:27

1 Answers1

1

You could implement a default constructor or method in the partial non-autogenrated class that handles the PropertyChanged event (that I assume that the auto-generated SendPropertyChanged method raises), and then update and raise the PropertyChanged event for the PaySum_Total_Pay in the event handler. Something like this:

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)));
        }
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • I got this to work by adding to `partial void OnChange();` stub with Linq created in the default method/constructor since I could do anything with `public Payroll_SummaryReview()`. Thanks, now I just have to fix everything else! – Jeremiah Halstead Mar 02 '22 at 18:08