Вам необходимо использовать 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