我正在使用 WPF/MVVM。 我将 textbox.Text 绑定到视图模型中的可为空的双精度值。 UpdateSourceTrigger = PropertyChanged 而不是 Lostfocus。因此,当使用我正在使用的转换器内的 Double.Parse(textbox.Text) 输入每个数字时, double 属性将被更新。我在这里使用 PropertyChanged 和转换器,因为我需要进行一些其他验证检查。
我的问题是我需要输入“1.69”。 当我输入“1”时,它会作为“1”添加到属性中。 接下来我输入“.”,但它没有添加为“1”。因为 double.parse 将数字保存为“1”
所以我不能添加小数。请帮忙。预先感谢。
如果您使用
StringFormat=\{0:n\}
,应该没问题。例如:
<TextBox Text="{Binding FooValue, UpdateSourceTrigger=PropertyChanged,
StringFormat=\{0:n\}}"/>
或者只使用转换器。例如:
<Window.Resources>
<helper:DoubleConverter x:Key="DoubleConverter" />
</Window.Resources>
...The code omitted for the brevity
<TextBox Text="{Binding Amount, UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource DoubleConverter}}"/>
和
DoubleConverter
:
public class DoubleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// return an invalid value in case of the value ends with a point
return value.ToString().EndsWith(".") ? "." : value;
}
}
如果输入的字符串以
0
结尾,您可以在转换之前附加 .
。
我刚刚在这篇文章的评论中使用转换器做了一个测试应用程序:当 TextBox 绑定到 double 并输入小于 -1 的负数时出现问题,它对我来说效果很好。
我的视图模型:
class MainWindowViewModel
{
private double? myDouble;
public double? MyDouble
{
get { return myDouble; }
set
{
myDouble = value;
}
}
}
我的测试主窗口:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
>
<Window.Resources>
<local:DecimalConverter x:Key="converter" />
</Window.Resources>
<Grid>
<TextBox
x:Name="textBox"
HorizontalAlignment="Left"
Text="{Binding MyDouble, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource converter}}"
Height="23"
Margin="10,185,0,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"/>
<TextBox
x:Name="textBox1"
HorizontalAlignment="Left"
Text="{Binding MyDouble}"
Height="23"
Margin="10,248,0,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"/>
</Grid>
</Window>
文本框 1 按预期从文本框更新。尝试一下 Avneesh 的转换器。
这篇文章已有 7 年历史,但鉴于它仍然是一个问题,我想发布我的解决方案以及我对问题的理解。
问题是,当您使用 updatesourcetrigger=propertychanged 在框中键入时,输入每个字符后,应用程序将运行解析为双精度。问题是对于像“1”这样的东西。这是要解析的有效字符串,在您输入小数并清除小数后,它会立即返回“1”。
我解决这个问题的方法是绑定到一个字符串属性,该属性有两个支持字段。一个是双精度数,一个是字符串。
private double _doubleEntry;
private string _stringEntry;
public string StringEntry {
get => _stringEntry;
set {
_stringEntry = value;
if (double.TryParse(value, out double temp))
_doubleEntry = temp;
OnPropertyChanged(nameof(StringEntry));
}
这将始终返回用户输入的字符串,但仅在有效输入时存储双精度值。
如果您想显示 WPF 控件中 _doubleEntry 变量中的值,您需要将其 LostFocus 绑定到一个方法,该方法从 _doubleEntry 中获取值并将其分配给您的控件的相应字段。
所以你的 Xaml 看起来像这样。
<TextBox
LostFocus="{Binding StringEntryLostFocus}"
Text="{Binding StringEntry, UpdateSourceTrigger=PropertyChanged}" />
LostFocus 方法的代码是
public void StringEntryLostFocus(object sender, EventArgs e) {
var tb = sender as System.Windows.Controls.TextBox;
if (tb is null) return;
tb.Text = _targetTempDouble.ToString();
请随时对我的回答发表反馈。这是我第一次关于堆栈溢出。