You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中如何让TextBox的UpdateSourceTrigger更新先于LostFocus事件执行?

解决WPF中TextBox LostFocus事件前先更新绑定源的问题

你的问题核心是:绑定设置了UpdateSourceTrigger=Explicit导致LostFocus事件触发时,DescontoTotal还没同步文本框的输入值,但又不能用PropertyChanged(因为转换器需要输入完成后再格式化)。这里有个简单直接的解决方案,完全贴合你的需求:


方法:在自定义LostFocus事件开头手动触发绑定源更新

既然你用了Explicit触发模式,我们只需要在执行计算逻辑前,手动调用绑定的UpdateSource()方法,强制把文本框的最新值同步到DescontoTotal上。修改你的事件处理代码如下:

private void txtTotaisNfe_LostFocus(object sender, RoutedEventArgs e)
{
    // 先手动同步绑定源,确保DescontoTotal是最新值
    var textBox = sender as TextBox;
    if (textBox != null)
    {
        var bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty);
        bindingExpr?.UpdateSource();
    }

    // 现在可以放心使用更新后的DescontoTotal进行计算了
    foreach (var item in _lsProdutos)
    {
        item.Desconto = (ThisDataContext.DescontoTotal / ThisDataContext.TotalProdutos * item.ValorProduto).Round();
    }
}

为什么这个方法可行?

  1. 保留转换器逻辑:ConvertBack依然只会在你调用UpdateSource()时执行(也就是LostFocus事件内),完全满足你「输入完整值后再转换为两位小数」的要求,不会像PropertyChanged那样每输入一个字符就触发转换。
  2. 确保数据同步:手动更新放在事件逻辑最开头,保证后续计算用的是文本框的最新输入值,解决了之前DescontoTotal未更新的问题。
  3. 改动最小:不需要修改XAML的绑定设置,只需要在事件处理里加几行代码,成本很低。

备选方案:调整事件执行顺序(更复杂)

如果你不想手动调用UpdateSource(),也可以通过调整事件注册顺序,让自定义的LostFocus处理逻辑在WPF默认的绑定更新之后执行。不过这种方法需要在代码后台注册事件,而不是在XAML里直接绑定:

public YourWindow()
{
    InitializeComponent();
    // 注册LostFocus事件,指定让自定义处理程序在默认逻辑之后执行
    txtTotaisNfe.AddHandler(TextBox.LostFocusEvent, new RoutedEventHandler(txtTotaisNfe_LostFocus), handledEventsToo: false);
}

然后把XAML里的LostFocus="txtTotaisNfe_LostFocus"去掉。不过这种方法依赖WPF的路由事件执行顺序,不如第一种手动更新的方式直观可控,所以更推荐第一种方案。


内容的提问来源于stack exchange,提问作者Renan Valentim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:37:28