NumericUpDown应该是平常用的比较多的控件了,省去了用TextBox时验证是否是数字等一系列麻烦的事。
其允许设置一个小数位数以格式化显示出来的数据,虽然最终获取的Value值和这个小数位没关系,比如在控件中输入3.1415926,如果设了小数位数是2,那么显示的会是3.14,而实际获取的Value还是等于3.1415926。
可惜小数位数只能设置为0-15之间的一个准确的整数,而我们的用户也请不一定知道其中的奥妙,他们只想输入多少显示多少。
那就添加个行为,用于在用户输入值的时候自动改变设定的小数位数。
代码如下:
public
class
AutoDecimalPlacesBehavior : Behavior
<
NumericUpDown
>
{
public AutoDecimalPlacesBehavior()
{
}
protected override void OnAttached()
{
base .OnAttached();
this .AssociatedObject.ValueChanging += new RoutedPropertyChangingEventHandler < double > (AssociatedObject_ValueChanging);
this .AssociatedObject.ValueChanged += new RoutedPropertyChangedEventHandler < double > (AssociatedObject_ValueChanged);
}
protected override void OnDetaching()
{
base .OnDetaching();
this .AssociatedObject.ValueChanging -= new RoutedPropertyChangingEventHandler < double > (AssociatedObject_ValueChanging);
this .AssociatedObject.ValueChanged -= new RoutedPropertyChangedEventHandler < double > (AssociatedObject_ValueChanged);
}
void AssociatedObject_ValueChanging( object sender, RoutedPropertyChangingEventArgs < double > e)
{
this .SetDecimalPlaces(e.NewValue);
}
void AssociatedObject_ValueChanged( object sender, RoutedPropertyChangedEventArgs < double > e)
{
this .SetDecimalPlaces(e.NewValue);
}
private void SetDecimalPlaces( double value)
{
var values = value.ToString().Split( ' . ' );
this .AssociatedObject.DecimalPlaces = values.Length == 2 ? Math.Min(values[ 1 ].Length, 15 ) : 0 ;
}
}
{
public AutoDecimalPlacesBehavior()
{
}
protected override void OnAttached()
{
base .OnAttached();
this .AssociatedObject.ValueChanging += new RoutedPropertyChangingEventHandler < double > (AssociatedObject_ValueChanging);
this .AssociatedObject.ValueChanged += new RoutedPropertyChangedEventHandler < double > (AssociatedObject_ValueChanged);
}
protected override void OnDetaching()
{
base .OnDetaching();
this .AssociatedObject.ValueChanging -= new RoutedPropertyChangingEventHandler < double > (AssociatedObject_ValueChanging);
this .AssociatedObject.ValueChanged -= new RoutedPropertyChangedEventHandler < double > (AssociatedObject_ValueChanged);
}
void AssociatedObject_ValueChanging( object sender, RoutedPropertyChangingEventArgs < double > e)
{
this .SetDecimalPlaces(e.NewValue);
}
void AssociatedObject_ValueChanged( object sender, RoutedPropertyChangedEventArgs < double > e)
{
this .SetDecimalPlaces(e.NewValue);
}
private void SetDecimalPlaces( double value)
{
var values = value.ToString().Split( ' . ' );
this .AssociatedObject.DecimalPlaces = values.Length == 2 ? Math.Min(values[ 1 ].Length, 15 ) : 0 ;
}
}
代码还是非常简单,注册了ValueChanging和ValueChanged两个事件,为了确保万无一失。
当控件内的值改变时我们就能获取当前的新值,然后对新值进行一点点小处理就好了,当然还是要确保0<=DecimalPlaces<=15。