Как связать события LostFocus и GotFocus для просмотра команд модели? - PullRequest
0 голосов
/ 12 февраля 2020

Я новичок в C# и MVVM подходе, я создал такой TextBox

<TextBox x:Name="Tb_fps"
         Grid.Column="0"
         Text="{Binding FPS, UpdateSourceTrigger=PropertyChanged}"
         x:FieldModifier="private" 
         Margin="4,4,0,4" 
         HorizontalAlignment="Stretch"/>

и, как вы можете видеть, я использую UpdateSourceTrigger=PropertyChanged, но дополнительно я хотел бы использовать LostFocus и GotFocus события ...

Но я не могу с этой реализацией DataBinding ...

Вопрос - как обрабатывать все эти события в одном представлении TextBox ?

РЕДАКТИРОВАТЬ

Связано с ответом @Joe H

enter image description here

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020

Вы можете привязать любое событие из XAML с помощью пакета Microsoft.Xaml.Behaviors.Wpf .
После установки пакета вы должны включить пространство имен поведения (xmlns:i="http://schemas.microsoft.com/xaml/behaviors) в свой XAML файл. Затем вы можете использовать разметку <i:InteractionTrigger> в вашем элементе управления (это XAML behaviour).

Эта разметка позволяет вам объявить EventTrigger, который работает немного как триггеры стиля, если вы знакомы с этим. Вы можете указать управляющее событие, к которому хотите подключиться, и затем объявить TriggerAction разметку для реакции на событие.
Скорее всего, вы захотите использовать TriggerAction типа InvokeCommandAction, который будет связывать к команде в вашей модели представления.

Ваш код будет выглядеть следующим образом:

<TextBox
    x:Name="Tb_fps"
    Grid.Column="0"
    Margin="4,4,0,4"
    HorizontalAlignment="Stretch"
    x:FieldModifier="private"
    Text="{Binding FPS, UpdateSourceTrigger=PropertyChanged}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="LostFocus">
            <i:InvokeCommandAction Command="{Binding LostFocusCommand}" />
        </i:EventTrigger>
        <i:EventTrigger EventName="GotFocus">
            <i:InvokeCommandAction Command="{Binding GotFocusCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

Редактировать: я изменил System. Windows .Интерактивный пакет на Microsoft.Xaml.Behaviors.Wpf , который является более новым и поддерживаемым пакетом.

2 голосов
/ 12 февраля 2020

Вам необходимо использовать EventTrigger из пространства имен

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

.

Это позволяет преобразовать событие в шаблон ICommand. Также вам не нужен EventSource, так как он используется по умолчанию для запуска привязки. Это будет Xaml, и код ViewModel следует

<Grid>
    <StackPanel>
        <TextBox Text="{Binding Text}" Height="40" Width="80">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="LostFocus">
                    <i:InvokeCommandAction Command="{Binding LostFocusCommand}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="GotFocus">
                    <i:InvokeCommandAction Command="{Binding GotFocusCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
        <TextBox Text="Need something to change focus to" Height="40" Width="80" />
    </StackPanel>
</Grid>

ViewModel:

public class MyWindowViewModel : INotifyPropertyChanged
{
    private string _text;

    public string Text
    {
        get => _text;
        set
        {
            _text = value;
            OnPropertyChanged();
        }
    }

    public ICommand LostFocusCommand => new ActionCommand(ExecuteLostFocus);

    private void ExecuteLostFocus()
    {
        Console.WriteLine("LostFocus");
    }

    public ICommand GotFocusCommand => new ActionCommand(ExecuteGotFocus);

    private void ExecuteGotFocus()
    {
        Console.WriteLine("GotFocus");
    }


    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Кроме того, вы должны знать, что свойство Text в ViewModel не обновляется, пока TextBox не потеряет фокус. Если вы хотите захватывать текст при его изменении, необходим обработчик TextChanged

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...