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 绑定确实更新得太晚了的主要内容,如果未能解决你的问题,请参考以下文章
Mvvm KeyDown的实现以及TextBox绑定的属性不更新问题的解决
C# 如何通过textbox修改dataGridView中的值单击button并保存到数据库中