使用WPF双向数据绑定更改setter属性中的值

使用WPF双向数据绑定更改setter属性中的值

问题描述:

我有一个TextBox绑定到一个Entity对象上的Text属性。
我希望能够在某些情况下重新格式化用户输入的文本。如果用户输入2/4(一小部分) - 我想将其更改为1/2。

I have a TextBox that is bound to a Text-property on an Entity-object. I'd like to be able to re-format the text the user enters in some circumstances - e.g. if the user enters "2/4" (a fraction) - I'd like to change that to "1/2".

通过设置部分的Text属性,我可以更改Entity对象上的值,但是不会出现在TextBox中 - 它仍然读为2/4?

Via the "set-part" of the Text-property, I can change the value on the Entity-object, but that doesn't appear in the TextBox – it still reads "2/4"?

这样做的原因是WPF中的绑定系统是智能的,当您更改TextBox中的值时,它假定PropertyChanged事件将触发该属性并忽略它。

The reason for this is that the binding system in WPF is "intelligent" and when you change the value in the TextBox it assumes that the PropertyChanged event will fire for that property and ignores it.

您可以通过调用以下方式强制TextBox刷新其绑定:

You can force the TextBox to refresh its bindings by calling:

textBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget();

但困难是找到一个很好的地方来挂钩。显然你的数据对象不能因为它没有引用TextBox实例。您可以在保存TextBox的窗口中将其链接到数据对象的PropertyChanged事件处理程序,但不会感觉很干净。

but the difficulty is finding a good place to hook this in. Obviously your data object can't do it since it has no reference to the TextBox instance. You could do it in the window that holds the TextBox by linking it to the PropertyChanged event handler of the data object, but that doesn't feel very clean.

如果我想到一个更好的解决方案,我会编辑这个回复,但至少这就解释了绑定不起作用。

I'll edit this response if I think of a better solution, but at least this explains the reason that the binding isn't working.

阿哈!将绑定更改为IsAsync = true:

Aha! Changing the binding to IsAsync=true:

<TextBox x:Name="textBox" Text="{Binding Path=TestData, IsAsync=true}"/>

出现改变行为,以便 注意PropertyChanged事件被setter触发。

Appears to alter the behaviour so that it does pay attention to the PropertyChanged event when it's fired by the setter.

作为附录(32个月后)此行为已经是在.NET 4中更改和您将不再需要IsAsync。

As an addendum (32 months later) this behaviour has been changed in .NET 4 and you won't need the IsAsync anymore.