i wrote custom control base on TextBox which has also Minimum and Maximum inputs as follows:
public class NumericTextBox : TextBox
{
static NumericTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericTextBox), new FrameworkPropertyMetadata(typeof(NumericTextBox)));
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(int), typeof(NumericTextBox), new PropertyMetadata(default(int)));
public int Minimum
{
get { return (int)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(int), typeof(NumericTextBox), new PropertyMetadata(100));
public int Maximum
{
get { return (int)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public new static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(int), typeof(NumericTextBox),
new FrameworkPropertyMetadata(
default(int),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
null,
CoerceCurrentValue),
IsValid);
public new int Text
{
get { return (int)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private static object CoerceCurrentValue(DependencyObject d, object baseValue)
{
var numericTextBox = (NumericTextBox)d;
var intValue = (int)baseValue;
if (intValue < numericTextBox.Minimum) intValue = numericTextBox.Minimum;
if (intValue > numericTextBox.Maximum) intValue = numericTextBox.Maximum;
if ((int)baseValue != intValue)
numericTextBox.Text = intValue;
return intValue;
}
private static bool IsValid(object value)
{
if (value == null)
return false;
int intValue;
var result = Int32.TryParse(value.ToString(), out intValue);
return result;
}
}
and in my xaml i call it:
<controls:NumericTextBox
Grid.Row="0"
Grid.Column="1"
Margin="5"
VerticalAlignment="Center"
Text="{Binding Test, UpdateSourceTrigger=PropertyChanged}"
Minimum="0"
Maximum="100"
/>
it is bind to Test property in my view model (as int). everything works good until i type a character and i get binding error:
System.Windows.Data Error: 7 : ConvertBack cannot convert value '1a' (type 'String'). BindingExpression:Path=Text; DataItem='NumericTextBox' (Name=''); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') FormatException:'System.FormatException: Input string was not in a correct format. at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) at System.String.System.IConvertible.ToInt32(IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture) at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'
it may be because the original Text property in TextBox is string... but i'm not sure. please assist on that.