Today I’ve spent some time on playing with some piece of code that had to ensure that on screen in some NumericTextBox depending on situation we show one of the two values – either one automatically calculated or either another user entered.
If value was automatically calculated we show it in that text box, but if user changes it we still keep calculated value untouched (double? CalculatedMileage) but work with another value (double? EnteredMileage). As you see we cannot bind any of these directly to the view.
So, how do we bind two sources (fields) to one target (textbox) on the UI?
I came to some solution with which I’m not completely satisfied, but at least I like it much more than it was before my changes.
Here is binding (I did not change it):
<UserControls:NumericTextBox AllowDecimals=”True”
Minimum=”0″ UseMinimum=”True”
Maximum=”999.999″ UseMaximum=”True”
MaxLength=”6″
Value=”{Binding Mileage, Mode=TwoWay}”
Now, Mileage property that I’m binding to the view has backing field _mileage, so I always get value for displaying by using simple getter. But on set I’m actually populating two fields _mileage and EnteredMileage like below:
private double? _mileage;
public double? Mileage
{
get
{
return _mileage;
}
set
{
_mileage = value;
EnteredMileage = value;
RaisePropertyChanged("Mileage");
}
}
This means that once I used setter I touched EnteredMileage.
What I display is _mileage and I when I display is when RaisePropertyChanged gets called. So keeping this in mind I do following stuff on screen setup:
_mileage = EnteredMileage.HasValue ? EnteredMileage : CalculatedMileage;
RaisePropertyChanged("Mileage");
If user initially entered some value we start operating with it and don’t touch calculated one, but if he did not, then we show calculated at first.
I may be bothering you, but I’m wondering if you know/see some more elegant solution for this stuff. I guess there must be some. And if there is no such, then use mine…