Textbox在UpdateSourceTrigger=PropertyChanged时Binding float double类型变量会有三个问题
1.不可以输入小数点
2.当输入0.10会自动变成0.1,既末尾是0的数字数会自动删掉最后一个0
3.当超过精度时会自动显示为科学计数法
本文在综合网上现有资源解决了这三个问题并且增加限制只可以输入数字
1.增加一个Convert
public class StringToNumberFloatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
NumberStyles numberStyles = System.Globalization.NumberStyles.Float;
//使界面不显示科学计数法
return Decimal.Parse(value.ToString(), numberStyles);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//可以输入“.”或者“,”,原理是使其报错则不对binding的变量赋值
string result = (value.ToString().EndsWith(".") ? "." : value).ToString();
result = (result.ToString().EndsWith(",") ? "," : result).ToString();
//可以输入末尾是0的小数,原理同上
Regex re = new Regex("^([0-9]{1,}[.,][0-9]*0)$");
result = re.IsMatch(result) ? "." : result;
return result;
}
}
2.增加一个Behavior使其不能输入除数字外其他字符
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace Util.Behaviours
{
public class OnlyDigitalBehavior : Behavior<TextBox>
{
private string lastRight = null;
public Type DigitalType
{
get
{
return (Type)GetValue(DigitalTypeProperty);
}
set
{
SetValue(DigitalTypeProperty, value);
}
}
public static readonly DependencyProperty DigitalTypeProperty =
DependencyProperty.Register("DigitalType", typeof(Type), typeof(OnlyDigitalBehavior), new PropertyMetadata());
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged += AssociatedObject_TextChanged;
InputMethod.SetIsInputMethodEnabled(this.AssociatedObject, false);
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
}
private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
Type digitalType = this.DigitalType;
if (textBox == null)
{
return;
}
if ((IsDigital(digitalType, textBox.Text) || string.IsNullOrEmpty(textBox.Text)) && lastRight != textBox.Text)
{
lastRight = textBox.Text;
}
else if (textBox.Text != lastRight)
{
textBox.Text = lastRight;
textBox.SelectionStart = textBox.Text.Length;
}
}
private bool IsDigital(Type targetType, string digitalString)
{
if (digitalString == "-")
{
return true;
}
if (targetType == typeof(Int16))
{
Int16 i = 0;
if (Int16.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(Int32))
{
Int32 i = 0;
if (Int32.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(Int64))
{
Int64 i = 0;
if (Int64.TryParse(digitalString, out i))
{
return true;
}
}
else if (targetType == typeof(float))
{
float f = 0;
if (float.TryParse(digitalString, out f))
{
return true;
}
}
else if (targetType == typeof(double))
{
double d = 0;
if (double.TryParse(digitalString, out d))
{
return true;
}
}
else if (targetType == typeof(decimal))
{
decimal d = 0;
if (decimal.TryParse(digitalString, out d))
{
return true;
}
}
return false;
}
}
}
3.用法
<UserControl x:Class="Workbench.Config"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behavior="clr-namespace:Util.Behaviours;assembly=Util"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:Behaviors="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d"
d:DesignHeight="800" d:DesignWidth="1200">
<Grid>
<TextBox Text="{Binding folatNumber,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource stringToNumberConverter}}" >
<i:Interaction.Behaviors>
<behavior:OnlyDigitalBehavior DigitalType="{x:Type sys:Single}" />
</i:Interaction.Behaviors>
</TextBox>
</Grid>
</UserControl>