TextBox 和默认 Button 绑定确实更新得太晚了

Posted

技术标签:

【中文标题】TextBox 和默认 Button 绑定确实更新得太晚了【英文标题】:TextBox and default Button binding does update too late 【发布时间】:2011-02-07 22:51:40 【问题描述】:

我有一个带有这两个控件的简单 WPF 对话框:

<TextBox Text="Binding MyText"/>
<Button Command="Binding MyCommand" IsDefault="True"/>

现在,当我在 TextBox 中输入一些文本并使用鼠标单击按钮时,一切正常:TextBox 将设置 MyText 并调用 MyCommand。

但是当我输入一些文本并按回车键“单击”默认按钮时,它不起作用。由于点击输入焦点不会离开文本框,因此绑定不会刷新 MyText。因此,当调用 MyCommand(有效)时,MyText 将包含旧数据。

如何在 MVVM 中解决此问题?在经典的代码隐藏中,我可能只会在 MyCommand 处理程序中调用“MyButton.Focus()”,但在 MVVM 中,MyCommand 处理程序对按钮一无所知。

那么现在呢?

【问题讨论】:

【参考方案1】:

使用值 PropertyChanged 将 UpdateSourceTrigger 添加到您的 TextBox。文本框的默认行为是在失去焦点时更新源。

<TextBox Text="Binding MyText, UpdateSourceTrigger=PropertyChanged"/>

【讨论】:

所以我需要将它添加到每个绑定中(因为我的键盘快捷键可能总是有可访问的按钮)?【参考方案2】:

试试这个。此代码将焦点移到单击的按钮上。因此绑定在命令处理之前完成。

    public App()
    
        EventManager.RegisterClassHandler(typeof(Button), Button.ClickEvent, new RoutedEventHandler(GenericButtonClickHandler));
    

    void GenericButtonClickHandler(object sender, RoutedEventArgs e)
    
        var button = sender as Button;
        if (button == null)
            return;
        if (button.IsDefault)
            button.Focus();
    

【讨论】:

那些不是默认按钮并通过使用它们的 alt 快捷方式激活的按钮呢?这对他们不起作用。 是的,山姆。你说得对 if (button.IsDefault) 不适用于通用解决方案。 但是这个解决方案的想法是在处理之前捕获所有点击,并将焦点放在一个按钮上。但不要在整个应用程序的任何可编辑控件中使用UpdateSourceTrigger +1 就我而言,这是最好的解决方案。将 UpdateSourceTrigger 更改为 PropertyChanged 会导致验证和脏检查出现问题。这为一个非常烦人的问题提供了一个全局解决方案。【参考方案3】:

一个解决方案是,创建自己的 OKButton 类,在 OnClick 方法中调用 Me.Focus。这将在 Click_Event 之前和绑定到按钮的任何命令之前调用。您只需要记住使用 OKButton 而不是设置 IsDefault=True

Public Class OKButton
  Inherits System.Windows.Controls.Button

  Public Sub New()
  MyBase.New()
  Me.Content = "OK"
  Me.IsDefault = True
  End Sub

  Protected Overrides Sub OnClick()
  Me.Focus()
  MyBase.OnClick()
  End Sub
End Class

【讨论】:

那些不是默认按钮并通过使用它们的 alt-shortcut 激活的按钮呢?这对他们不起作用。

以上是关于TextBox 和默认 Button 绑定确实更新得太晚了的主要内容,如果未能解决你的问题,请参考以下文章

关于WPF的绑定小问题

Mvvm KeyDown的实现以及TextBox绑定的属性不更新问题的解决

WPF:解决数据绑定时不更新数据的问题

C# 如何通过textbox修改dataGridView中的值单击button并保存到数据库中

数据绑定到 TextBox - 在代码中设置 Text 属性不会更新模型

Kendo UI:在 TextBox 中的 KeyPress 上强制更新 ViewModel