Reputation: 9384
In my application I have a TextBox
where the user can input a number beetween 1 and 10. The xaml of this TextBox
looks like:
<TextBox Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" x:Name="tbInput"/>
The property Value where the TextBox
is bound to looks like:
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(decimal), typeof(NumericUpDown), new PropertyMetadata((d, e) =>
{
((NumericUpDown)d).Value = (decimal)e.NewValue;
}));
public decimal Value
{
get { return (decimal)GetValue(ValueProperty); }
set
{
if (Value == value || value > Maximum || value < Minimum)
return;
SetValue(ValueProperty, value);
OnPropertyChanged("Value");
OnValueChanged();
}
}
It works if the user types in a number. But if the user types in a char or a string or something else than it doesn't work. I expected that my TextBox
wouldn't accept the invalid value but a breakpoint in the setter of the Value-Property is not reached.
What do I have to do to only allow numbers or to decline the user-input if it's not correct?
Upvotes: 0
Views: 876
Reputation: 128013
The statement
((NumericUpDown)d).Value = (decimal)e.NewValue;
in the PropertyChangedCallback doesn't make sense, because it just sets the Value property another time to the same value.
You should instead move the code from the property setter to the callback. Moreover, you should not call anything but SetValue
in the setter of the CLR wrapper of a dependency property. The reason is explained in the XAML Loading and Dependency Properties article on MSDN.
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(decimal), typeof(NumericUpDown),
new PropertyMetadata(
(d, e) =>
{
((NumericUpDown)d).OnValueChanged();
}));
public decimal Value
{
get { return (decimal)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value);}
}
In order to validate the value passed to your dependency property, you may use the DependencyProperty.Register overload that takes a ValidateValueCallback
argument:
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(decimal), typeof(MainWindow),
new PropertyMetadata((d, e) => ((NumericUpDown)d).OnValueChanged()),
v => (decimal)v >= Minimum && (decimal)v <= Maximum);
Upvotes: 1