Skip to content

NumericUpDown sets Value property too early (causing bad binding validation) #90

Description

@xceedsoftware

Reyhn[CodePlex]
Hello!
nbsp
I found a smaller issue that causes ugly results when binding to the Value-property of the NumericUpDown controls (i used the DecimalUpDown).
When using data binding, it seems that the new value being bound to the source's Value-property is being set too early. This will (in the example below) cause an exception, even though the Value-property will be coerced to the Maximum/Minimum property.
nbsp
In the example below, Maximum is set to 4. If the Value currently is 4, pressing the up-arrow or the increment-button will actually immediately set the Value to 5, cause a data binding validation exception, then coerce back down to 4 again. In my opinion, this
is incorrect. If the current Value is already at Maximum, the increments should never take place at all. Of course, this also applies to decrementing beyond Minimum. As it is right now, this will cause strange effects when binding because of the redundant
validation errors. For instance, the DataGrid is not very fond of this. (:
nbsp
I also provided a solution that works (see the bottom of this report).
However, I am not sure if this is the best way to solve it. The OnCoerceValue() of the UpDownBase should have handled this, but it seems that the data binding system does not automatically call this method before actually setting the value.
nbsp
Below is an example of the code that triggers the issue.
nbsp
MainWindow.xaml:
nbsp
ltextToolkit:DecimalUpDown
ShowButtonSpinner=quotTruequot
Minimum=quot2quot
Maximum=quot4quot
Value=quot{Binding Path=MyValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}quot

Increment=quot1quot
DefaultValue=quot3quotgt
lt/extToolkit:DecimalUpDowngt
nbsp
nbsp
nbsp
MainWindow.xaml.cs:
nbsp
private decimal _myValue = 3;
public decimal MyValue
{
get
{
return this._myValue;
}
set
{
if (value lt 2)
throw new ArgumentOutOfRangeException(quotvaluequot, value, quotToo low!quot);

if (value gt 4)
throw new ArgumentOutOfRangeException(quotvaluequot, value, quotToo high!quot);

this._myValue = value;
}
}
nbsp
nbsp
Below is an example of how to solve the issue. This will have to be implemented for ALL inheritors of NumericUpDown.
nbsp
DecimalUpDown.cs:
nbsp
protected override void OnIncrement()
{
// Original code.
//if (Value.HasValue)
// Value += Increment;
//else
// Value = DefaultValue;

if (Value.HasValue)
{
if (Value lt Maximum)
Value = OnCoerceValue(Value + Increment);
}
else
Value = DefaultValue;
}

protected override void OnDecrement()
{
// Original code.
//if (Value.HasValue)
// Value -= Increment;
//else
// Value = DefaultValue;

if (Value.HasValue)
{
if (Value gt Minimum)
Value = OnCoerceValue(Value - Increment);
}
else
Value = DefaultValue;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions