Здесь всё просто сделать через команду. MVVM здесь не требуется, это не про MVVM, это про команды.
Берём класс, упрощающий взаимодействие с командами и добавляем в проект, например в файл RelayCommand.cs.
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
public void Execute(object parameter) => _execute(parameter);
}
Назначаем DataContext окну прямо на него самого.
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
DataContext нужен для работы привязок Binding в XAML. (в MVVM он назначается на экземпляр класса вью-модели)
Теперь вместо обработчика создаём саму команду
public ICommand PingCommand { get; } = new RelayCommand(parameter =>
{
User user = (User)parameter;
// код
}, parameter => parameter is User); // это CanExecute если условие не выполняется, кнопка задизаблится
Кнопка проверяет CanExecute команды каждый раз перед выполнением команды примерно так:
if (command.CanExecute(parameter))
{
command.Execute(parameter);
}
То есть это даёт гарантию, что вы никогда не получите InvalidCastException в строчке (User)parameter. Ну и плюс кнопка сама задизаблится, это удобно.
Если у вас команда такая, что CanExecute всегда true, то его можно просто не указывать, он необязателен.
И просто прописываем команду в кнопку
<Button Content="Ping"
Command="{Binding PingCommand, RelativeSource={RelativeSource, AncestorType=Window}}"
CommandParameter="{Binding}"/>
Готово. Никаких x:Name не требуется.