WPF: привязка данных текстового поля не происходит, если вы активируете кнопку с мнемоническим



Предположим, что у вас есть текстовое поле, связанное со свойством элемента данных, и кнопка.
Если ввести текст в текстовое поле, а затем нажать на кнопку с помощью мыши, то в таком порядке происходят следующие события:




  • текст записывается из элемента управления в связанный элемент

  • событие нажатия кнопки срабатывает


Однако, если вы активируете кнопку с помощью мнемонического ключа, текстовое поле не теряет фокус. Похоже, что текст написан от элемента управления к связанному элементу только когда текстовое поле теряет фокус.

Есть ли известный обходной путь к этому? Я хочу, чтобы вы вели себя одинаково, независимо от того, нажимаете ли вы левую кнопку, вкладку на кнопку и нажимаете пробел или используете мнемонику.



Я приведу полный пример. Если вы наберете слово " 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; }
}
}
636   3  

3 ответов:

Самое простое решение, которое я нашел (кроме использования свойства UpdateSourceTrigger, как предложил Джозеф), - это переместить фокус на кнопку в ее событии Click. Событие щелчка кнопки запускается независимо от того, как кнопка "нажата" (с помощью клавиатуры или мыши).

Если вы хотите, чтобы текстовое поле сохраняло фокус, вы можете удерживать текущий элемент управления в переменной, затем переключить фокус на кнопку и немедленно вернуться к этому элементу управления. Не идеально, хотя, потому что положение каретки в текстовое поле изменится.

Вы правы-текстовое поле не обновляет привязку, пока фокус не будет потерян по умолчанию. Активация мнемоническим ключом-это не то, что приходило мне в голову раньше:)

Это неудачная ошибка, но вы можете установить привязку для обновления, когда пользователь вводит текст (см. свойство UpdateSourceTrigger ).

Как только я подробно объяснил вопрос, он становится очевидным.

  • Когда вы нажимаете кнопку с помощью мыши, кнопка получает фокус. Это приводит к потере фокуса текстового поля, что запускает действие привязки данных.
  • кнопка не получает фокус, когда вы используете мнемонику.

Если кнопка получает фокус, когда вы используете мнемонику, проблема решена.

Таким образом, мы добавляем одну строку кода, чтобы убедиться, что кнопка имеет фокус.
    private void OnApplyClicked(object sender, RoutedEventArgs e)
    {
        ((UIElement)sender).Focus();
        Widget w = (Widget)this.Resources["Widget"];
        MessageBox.Show(string.Format("WidgetName={0}", w.WidgetName));
    }

Comments

    Ничего не найдено.