WPF:如果激活具有助记符的按钮,则不会发生TextBox数据绑定

时间:2009-09-17 22:05:20

标签: wpf data-binding xaml

假设您有一个绑定到数据项属性的文本框和一个按钮。 如果在文本框中输入文本,然后用鼠标单击按钮,则按以下顺序发生以下事件:

  • 文本从控件写入绑定项
  • 触发按钮点击事件

但是,如果使用助记键激活按钮,则文本框不会失去焦点。似乎只有当文本框失去焦点时,文本才会从控件写入绑定项。

这有一个已知的解决方法吗?无论你左键单击按钮,选择按钮并按空格,还是使用助记符,我都想要相同的行为。

我将提供一个完整的例子。如果您输入单词“Hello”并按下按钮,则会出现一个消息框“WidgetName = Hello”。但如果你把它改成“Goodbye”并按下ALT-A,它仍会说“WidgetName = Hello”。

这是XAML代码

<Window x:Class="BindingOrder.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:BindingOrder"
    Title="Window1" Height="79" Width="282">
    <Window.Resources>
        <local:Widget x:Key="Widget" />
    </Window.Resources>
    <StackPanel Orientation="Horizontal" Height="30" VerticalAlignment="Top">
        <TextBox 
            Width="200" 
            Margin="3, 3, 3, 3" 
            Text="{Binding Source={StaticResource Widget}, Path=WidgetName}" />
        <Button  
            Click="OnApplyClicked" 
            Margin="3, 3, 3, 3">
            _Apply
        </Button>        
    </StackPanel>
</Window>

支持代码:

using System;
using System.Windows;

namespace BindingOrder
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void OnApplyClicked(object sender, RoutedEventArgs e)
        {
            Widget w = (Widget)this.Resources["Widget"];
            MessageBox.Show(string.Format("WidgetName={0}", w.WidgetName));
        }
    }

    public class Widget
    {
        public string WidgetName { get; set; }
    }
}

3 个答案:

答案 0 :(得分:3)

我发现的最简单的解决方案(除了使用UpdateSourceTrigger属性,正如约瑟夫建议的那样)是将焦点转移到Click事件中的按钮。无论按钮如何“点击”(通过键盘或鼠标),按钮的Click事件都会被触发。

如果您希望TextBox保持焦点,您可以将当前聚焦的控件保持在变量中,然后将焦点移至按钮并立即返回该控件。但不太理想,因为TextBox中的插入符号位置会发生变化。

答案 1 :(得分:2)

你没错 - 默认情况下,在焦点丢失之前,文本框不会更新绑定。通过助记键激活不是我之前发生的事情:)

这是一个不幸的问题,但你可以设置绑定在用户输入时更新(参见UpdateSourceTrigger属性)。

答案 2 :(得分:1)

一旦我详细解释了这个问题就很明显了。

  • 当您使用鼠标单击按钮时,按钮将获得焦点。这会导致TextBox失去焦点,从而触发数据绑定操作。
  • 使用助记符时,按钮不会获​​得焦点。

如果按钮在使用助记符时收到焦点,问题就解决了。

因此我们添加一行代码以确保按钮具有焦点。

    private void OnApplyClicked(object sender, RoutedEventArgs e)
    {
        ((UIElement)sender).Focus();
        Widget w = (Widget)this.Resources["Widget"];
        MessageBox.Show(string.Format("WidgetName={0}", w.WidgetName));
    }