gpt4 book ai didi

textbox - 当强制文本输入导致源值不变时,带有 UpdateSourceTrigger=PropertyChanged 的​​ TextBox 上的文本不会更新

转载 作者:行者123 更新时间:2023-12-02 01:22:13 26 4
gpt4 key购买 nike

我有一个文本框,其 Text 属性具有 TwoWay MultiBindingUpdateSourceTrigger 设置为 属性已更改。第一个 Binding 是一个依赖属性 (Value),它具有一个 PropertyChangedCallBack 函数,可将值四舍五入到小数点后一位。

文本框的目的是在用户键入时执行舍入,而不是在文本框失去焦点时执行舍入,因此 UpdateSourceTrigger 设置为 PropertyChanged

我遇到的问题是,如果输入的文本不会导致 Value 更改,则 Text 属性和 Value 会消失的同步。仅当舍入操作导致发生变化时,文本才会动态更新。例如,如果 TextValue 均为 123.4,并且用户在此之后键入 1,则 Value 将四舍五入为相同值 (123.4),但文本显示 123.41。但是,如果在 4 之后键入 9, 将向上舍入为 123.5。由于这一实际更改,文本随后更新为相同的 (123.5)。

是否有任何方法可以强制文本框从其源进行更新,即使源自上次触发以来未发生更改?我尝试过使用 BindingExpressionBase.UpdateTarget() 但这仅在 UpdateSourceTrigger 设置为 Explicit 时有效,不能用作 >Value 不再在可以调用 UpdateTarget 的合适时间之前更新(例如 TextInput 处理程序)。我尝试过其他方法,例如从绑定(bind)的 Value 显式更新 Text 值,强制临时对 Value 进行实际更改以调用更新,但这些“黑客”要么不起作用,要么导致其他问题。

任何帮助将不胜感激。

代码如下。

XAML 片段

<TextBox>
<TextBox.Text>
<MultiBinding Converter="{local:NumberFormatConverter}"
UpdateSourceTrigger="Explicit"
Mode="TwoWay">
<Binding Path="Value"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
Mode="TwoWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>

C# 代码片段

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
"Value", typeof(decimal), typeof(MainWindow),
new FrameworkPropertyMetadata(0m,
new PropertyChangedCallback(OnValueChanged)));

private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
obj.SetValue(ValueProperty, Math.Round((decimal)args.NewValue, 1));
}

需要转换器类

public class NumberFormatConverter : MarkupExtension, IMultiValueConverter
{
public static NumberFormatConverter Instance { private set; get; }

static NumberFormatConverter()
{
Instance = new NumberFormatConverter();
}

public override object ProvideValue(IServiceProvider serviceProvider_)
{
return Instance;
}

#region Implementation of IMultiValueConverter

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0].ToString();
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
var result = 0m;
if (value != null)
{
decimal.TryParse(value.ToString(), out result);
}
return new object[] { result };
}

#endregion
}

最佳答案

我在互联网上做了一些挖掘,结果发现这在 WPF 4 中被破坏了。有人与我有几乎相同的问题,在这里发布: http://www.go4answers.com/Example/textbox-shows-old-value-being-coerced-137799.aspx

“Answer 8”指出此问题在 WPF 4 中被破坏,并提出了一个解决方案,即实际使用 UpdateSourceTrigger="Explicit" 但处理 TextChanged 事件并调用 BindingExpression.UpdateSource () 强制文本框中的更改反射(reflect)在基础值中,就像 UpdateSourceTrigger="PropertyChanged" 一样,根据这篇文章: Coerce a WPF TextBox not working anymore in .NET 4.0

我实现了这个,但是你瞧,还有更多的副作用,特别是每次击键都会导致插入符号由于更新源代码并引发PropertyChanged而跳转到文本框的开头事件。而且,任何为了输入更多数字而输入的前导或尾随零或小数位都会立即被删除。因此,一个简单的条件来检查文本框解析的十进制值与基础值解决了这个问题。

以下事件处理程序就是所需要的:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var tb = (TextBox)e.Source;
MultiBindingExpression binding = BindingOperations.GetMultiBindingExpression(tb, TextBox.TextProperty);

decimal result = 0m;
decimal.TryParse(tb.Text, out result);

if ((decimal)GetValue(ValueProperty) != result && binding != null)
{
int caretIndex = tb.CaretIndex;
binding.UpdateSource();
tb.CaretIndex = caretIndex;
}
}

关于textbox - 当强制文本输入导致源值不变时,带有 UpdateSourceTrigger=PropertyChanged 的​​ TextBox 上的文本不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4128567/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com