I have an app that has been in production for awhile and yesterday I started getting emails about my app crashing. App built with latest Elements and DA. I did some debugging and i discovered this morning that now i seem to be caught in an loop in a PropertyChangedEvent. That event gets triggered from one field change, and in that event i update a second field, which then causes the event to get called again, and again, and again…
Is there a “proper” way to use this event in this manner without having your code go into a loop of death like this? As i said…this has worked up until now without any changes in this part of the code, so on a different level i’m a bit confused as to why this is an issue now.
How do i override the individual field setters? Do i need to move those declarations to the public section of the generated DA classes? I can’t edit the DA tabledefinitions classes since those are autogenerated by DA. What is the best approach to intercept the setters for individual fields?
So a class in question is a DA-generated Table Definition class?
As I understand you have 2 fields in a table that depend on each other and you need to keep them in sync.
There are several approaches for this (like defining separate calculated property or a method, or even modifying the generated source code).
Still you need to check a thing first
Please check your calculation logic. If there are 2 properties that depend on each other via some calculations then there should be no infinite event raisin loop. Take a look at this generated property setter:
method Employees.set__HomePhone(___value___: System.String);
if System.Collections.Generic.Comparer<System.String>.Default.Compare(self.f____HomePhone, ___value___) ≠ 0 then begin
self.f____HomePhone := ___value___;
PropertyChanged event in not raised at all if you try to set a property to a value matching its current value. So there should be no dead events loop.
For WPF data binding purposes it might be easier to define a separate composite property. F.e. let’s assume that we have a Table Defintion class defined as
Note that this class is defined as partial.
To add a property you need to add a separate code file (that won’t be changed if you regenerate the table definition classes) and put there this code:
Employees = public partial class
method get_FullName(): String;
exit self.FirstName + " " + self.LastName;
method set_FullName(value: String);
// Somehow split value to first name and last name parts
// Skipping this logic here
var fn := '....';
var ln := '....';
self.f____FirstName := fn;
self.f____LastName := ln;
property FullName: String read get_FullName write set_FullName;
This composite property now can be used for data binding etc. Note that changing this property also raises property notification events for related properties as well.