在WPF文本框的KeyUp事件中,textBox.Text的值是正确的,除非用户输入0.例如,如果用户输入5.88,则textBox.Text值为“5.88”。如果用户输入5.80,则textBox.Text值为“5.8”(0被删除)。我们只允许用户输入一个十进制数字,因此,如果它们输入5.80,我们要修剪0.问题是我们不能,因为修剪的代码只能看到“5.8”。操作完成后,文本框中仍会显示“5.80”,供用户查看。
知道为什么会这样吗?
注意:文本框中应用了转换器,但KeyUp事件将值设置为textBox.Text。因此,如果转换器产生5.8,则textBox.Text值将设置为“5.8”。
编辑:以下是一些代码:
<Window.Resources>
<converters:StringToBooleanConverter x:Key="stringToBooleanConverter" />
<converters:SecondsToMinutesConverter x:Key="secondsToMinutesConverter" />
</Window.Resources>
<TextBox Text="{Binding ApplyTimeInSeconds, Converter={StaticResource secondsToMinutesConverter},
TargetNullValue={x:Static sys:String.Empty}, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True, ValidatesOnExceptions=True}"
vab:Validate.BindingForProperty="Text"
Name="ApplyTimeTextBox"
KeyUp="ApplyTimeTextBox_KeyUp"
Width="75" VerticalAlignment="Center" Style="{StaticResource textBoxInError}"
IsEnabled="{Binding ElementName=applyTimeCheckbox, Path=IsChecked}"/>
private void ApplyTimeTextBox_KeyUp(object sender, KeyEventArgs e)
{
ViewUtility.RemoveExtraDecimalDigits(sender as TextBox, 1);
}
// We don't want to allow more than one decimal position. So, if the user types 4.38, remove the 8. Or change 4.389 to 4.3.
internal static void RemoveExtraDecimalDigits(TextBox textBox, int numberOfDecimalDigitsAllowed)
{
if (!textBox.Text.Contains(".")) { return; }
string originalText = textBox.Text;
textBox.Text = GetValueWithCorrectPrecision(textBox.Text, numberOfDecimalDigitsAllowed);
// If the text changed, move the cursor to the end. If there was no change to make, or maybe the user hit the
// HOME key, no reason to move the cursor.
if (textBox.Text != originalText)
{
MoveCursorToEnd(textBox);
}
}
private static string GetValueWithCorrectPrecision(string textValue, int numberOfDecimalDigitsAllowed)
{
int indexOfDecimalPoint = textValue.IndexOf('.');
string[] numberSection = textValue.Split('.');
if (numberSection[1].Length > numberOfDecimalDigitsAllowed)
{
// Keep the decimal point and the desired number of decimal digits (precision)
return textValue.Remove(indexOfDecimalPoint + numberOfDecimalDigitsAllowed + 1);
}
return textValue;
}
private static void MoveCursorToEnd(TextBox textBox)
{
textBox.Select(textBox.Text.Length, 0); // Keep cursor at end of text box
}
这是转换器:
public class SecondsToMinutesConverter : IValueConverter
{
#region IValueConverter Members
/// <summary>
/// Converts a value from the source (domain object/view model) to the target (WPF control).
/// </summary>
/// <param name="value">The value produced by the binding source.</param>
/// <param name="targetType">The type of the binding target property.</param>
/// <param name="parameter">The converter parameter to use.</param>
/// <param name="culture">The culture to use in the converter.</param>
/// <returns>
/// A converted value. If the method returns null, the valid null value is used.
/// </returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null) { return null; }
decimal bindingSourceValueAsDecimal = System.Convert.ToDecimal(value, CultureInfo.CurrentCulture);
return Decimal.Round(bindingSourceValueAsDecimal / 60, 2);
}
/// <summary>
/// Converts a value from the target (WPF control) to the source (domain object/view model).
/// </summary>
/// <param name="value">The value that is produced by the binding target.</param>
/// <param name="targetType">The type to convert to.</param>
/// <param name="parameter">The converter parameter to use.</param>
/// <param name="culture">The culture to use in the converter.</param>
/// <returns>
/// A converted value. If the method returns null, the valid null value is used.
/// </returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == null) { return null; }
decimal bindingTargetValueAsDecimal;
if(Decimal.TryParse(value.ToString(), out bindingTargetValueAsDecimal) == false) { return DependencyProperty.UnsetValue; }
return Math.Round(bindingTargetValueAsDecimal * 60, 2);
}
#endregion
}
答案 0 :(得分:0)
实际上,我试图重现行为,没有转换器(因为我不知道它是如何约束的),如果我很好地预期行为,它运作良好......
当我输入5.88时,最后一个数字被删除(我得到5.8)。 当我输入5.80时,最后一个数字也被删除(我得到5.8)。
你可以更具体地说明你不能做什么吗? 你试过没有任何转换器吗?或者您可以使用转换器使用XAML更新代码吗?
答案 1 :(得分:0)
建议您使用PreviewKeyUp或PreviewTextInput而不是KeyUp事件。
作为替代方案,您可能希望屏蔽文本框,或者
1.使用MaskedTextBox,或
2. modifying the behaviour of textbox使用附加财产。
如果是2,您可能需要根据需要修改ValidateValue函数。