This is more of an architecture / design question.
I have run into a few projects in the past written in WPF/Windows Forms, etc. that have complex screens with a lot of fields and these fields are connected to each other (their values depend on each other with some logic involved).
These projects I have taken on after they were implemented, and I found a lot of events / data bind hell - what I mean by this is that because all these fields are depending on others they have implemented INotifyPropertyChanged and other fields are being modified as a result. This causes the same fields being updated 5-6 times when the screen loads and the order in which fields are populated causes horrible bugs. (For example, Date was set before Job Type, instead of after Job Type, so I end up with a different Job Fee.)
To make matters worse, some hacks are implemented on UI events (for example, DropDown changed to update field X) while others are in the domain model that the UI binds to.
Basically, it's a huge mess, and I just want to know what the best way to implement something like this is if I was to start from scratch. Or is it a good idea to avoid such a complex screen in the first place?
I would try to keep the business logic out of the property setters as much as possible.
First of all, if several properties are needed for one calculation, I'd write one method that does the calculation, and call that method when appropriate. E.g. if all different combinations of property values make sense, one could just call the method in the setters of each property, making sure that the same code runs any time one of the properties is changed. If you only can evaluate special combinations of property values, you could either implement a command and let the user decide when to calculate the resulting changes, or you could provide feedback through validation, and only evaluate the property changes if the combination is valid. If there are several interdependent properties, I often use a "ChangeInitiator" variable to indicate what property has changed, so that it is clear in the calculation method which property is responsible for the change and which others should change as a result. Basically, this is the same as doing one part of the calculation in each property setter, but I find that it helps me to keep an overview of things if the different parts of the relationship are all in one method.
In a program I wrote once, I had some calculations running on a background thread periodically, so I would just set a flag whenever a piece of data changed that required a new calculation, and do all the updates based on a timer every second or so... that could also help you get the logic more straight, and it avoids to have the calculation run several times for one set of related changes.
With regard to change notification, I'd really try to only use it for UI data binding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With