WPF: TextBox dataBinding doesn't happen if you activate button with mnemonic

Suppose you have a text box associated with an item property and a button. If you enter text in the text box, then click the button with the mouse, the following events will happen in the following order:

  • Text is written from the control to the associated element
  • Button click event

However, if you activate the button with a mnemonic key, the text box does not lose focus. It seems that text is written from the control to the bound element only when the textbox loses focus.

Is there a known workaround? I need the same behavior if you left click on a button, tab on a button and press spacebar, or use a mnemonic.

I'll give you a complete example. If you type the word "Hello" and click the button, you get the "WidgetName = Hello" window. But if you changed it to "Goodbye" and press ALT-A, it still says "WidgetName = Hello".

Here's the XAML code

<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>

      

And the helper code:

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; }
    }
}

      

+2


source to share


3 answers


The simplest solution I have found (other than using the UpdateSourceTrigger property as Joseph suggested) is to switch focus to the button in the Click event. The Click Event button fires regardless of how the button is pressed (using the keyboard or mouse).



If you wanted the TextBox to remain focused, you could hold the currently controlled control in a variable and then switch focus to the button and immediately return to that control. Not ideal because the caret position in the TextBox will change.

+3


source


You're right - the textbox doesn't update the anchor until focus is lost by default. Activation with a mnemonic key is not something that came to me before :)



This is a failed attempt, but you can set the binding to update on user input (see the UpdateSourceTrigger property ).

+2


source


Once I have explained the question in detail, it becomes obvious.

  • When you click a button with your mouse, the button receives focus. This causes the TextBox to lose focus, which triggers the data binding action.
  • The button does not receive focus when using mnemonics.

If the button gets focus when using mnemonics, the problem is solved.

So we add one line of code to make the button have focus.

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

      

+1


source







All Articles