Подтвердить что ты не робот

WPF MVVM: TextBox и привязка Button по умолчанию обновляется слишком поздно

У меня есть простой диалог WPF с этими двумя элементами управления:

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

Теперь, когда я ввожу некоторый текст в TextBox и нажимаю кнопку с помощью мыши, все работает так, как ожидалось: TextBox будет вызывать MyText и MyCommand.

Но когда я ввожу какой-то текст и нажимаю кнопку "click" по умолчанию, это не работает. Так как при попадании в фокус не покидает TextBox, привязка не будет обновлять MyText. Поэтому, когда MyCommand вызывается (который работает), MyText будет содержать старые данные.

Как это исправить в MVVM? В классическом кодировании я, вероятно, просто назвал бы "MyButton.Focus()" в обработчике MyCommand, но в MVVM обработчик MyCommand ничего не знает о кнопке.

Итак, что теперь?

4b9b3361

Ответ 1

Добавьте UpdateSourceTrigger в свой TextBox со значением PropertyChanged. Поведение текстового поля по умолчанию заключается в обновлении источника, когда он потерял фокус.

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

Ответ 3

Одно решение ist, чтобы создать свой собственный класс OKButton, который вызывает Me.Focus в OnClick-Method. Это будет вызвано перед 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