How to avoid a databinding / events hell on a complex screen? How to avoid a databinding / events hell on a complex screen? wpf wpf

How to avoid a databinding / events hell on a complex screen?


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.


We have fairly complex UIs (including several related fields of different types in, say for example a Row in a DataGrid) and the MVVM pattern has worked pretty well for us. All the properties coming from the Model and exposed to the View that have complex logic related are "wrapped" by an equivalent property in the ViewModel, which has no Backing Field, but rather points directly to the Model:

public class SomeComplexViewModel{    public SomeModel Model {get;set;}    public string SomeCrazyProperty    {       get       {          return Model.SomeCrazyProperty;       }       {          Model.SomeCrazyProperty = value;          //... Some crazy logic here, potentially modifying some other properties as well.       }    }}<TextBox Text="{Binding SomeCrazyProperty}"/>

This removes the "initial value" problem, as the initial value read by the Binding is actually the real value coming from the Model, and thus the logic placed in the Setter is executed only when needed.

Then, for dummy properties (which have no logic behind), we bind directly from the View to the Model:

<TextBox Text="{Binding Model.SomeRegularProperty}"/>

This reduces the bloat in the ViewModel.

With regard to events in the code behind, I totally avoid that. My code behind files are almost always one InitializeComponent() and nothing else.

Only View-Specific logic is placed in the code behind (such as animations stuff, etc), when it cannot be directly done in XAML, or is easier to do in code (which is not the case most of the time).

Edit:

It's important to mention that the winforms binding capabilities are a joke compared to the XAML-based ones. could that be the cause you're seeing those horrible messes in those projects?