在开发 markdown-mail 时遇到了一些诡异的情况。代码是这么写的:

<TextBox Text="{Binding Text, Mode=TwoWay}"/>

然而在 TextChanged 事件之后延时执行了一些操作时,从 ViewModel 里拿到的值却始终是旧的。

阅读本文将了解其原因和解决办法。


无论是 WPF 还是 UWP,Binding 中都有 UpdateSourceTrigger 属性。

在 WPF 中,其可取的值为:

public enum UpdateSourceTrigger
{
    Default,
    PropertyChanged,
    LostFocus,
    Explicit
}

在 UWP 中,其可取的值为:

public enum UpdateSourceTrigger
{
    Default,
    PropertyChanged,
    Explicit
}

这些值代表的含义是:

  • Default
    • 默认值,多数情况下与 PropertyChanged 一样,然而TextBox.Text 属性来说,却是 LostFocus(WPF)或 Explicit(UWP)
  • Explicit
    • 必须在显式地调用 BindingExpression.UpdateSource 的情况下才会更新源值。
  • LostFocus(WPF 专属,不过 UWP 的预览版里也有)
    • 目标控件失去焦点的时候更新源值。
  • PropertyChanged
    • 绑定的目标值改变的时候就会更新源值,至于检测方法,则完全由 WPF/UWP 的绑定系统完成

于是,为了解决一开始的问题,我们需要在 TextBox 的 Text 属性的双向绑定里重新设置新的 UpdateSourceTrigger 的值。

<TextBox Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

没错,就是加这半句就好了。

参考资料


本文会经常更新,请阅读原文: https://walterlv.github.io/uwp/2017/09/25/binding-update-source-trigger.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系