0

дорогие друзья! Тыкните пожалуйста мое лицо в ссаную тряпку, но никак не могу сообразить...

Есть таблица DataGrid: введите сюда описание изображения

Хочу при нажатии на Кнопку Ping в колонке Operations, получить значение из колонки IP Adress текущий строки... для дальнейших манипуляций.

Datagrid заполняю обычным кодом

ObservableCollection<User> users = new ObservableCollection<User>();

users.Add(new User { ... );

В Xaml у меня просто:

<DataGridTemplateColumn.CellTemplate>
&lt;DataTemplate&gt;

    &lt;Button Content=&quot;Ping&quot; Click=&quot;Button_Click&quot;/&gt;

&lt;/DataTemplate&gt;

</DataGridTemplateColumn.CellTemplate>

Обработчик кнопки (пусто):

private void Button_Click(object sender, RoutedEventArgs e)
{
    \\ я так понимаю тут я должен как-то отловить нужную строку...хз как..и получить
    \\ данные из ячейки строки, которая была выбрана..
}

Подскажите пожалуйста как это сделать!!! Без всяких MVVM (для меня это пока дремучий лес!)

Cost
  • 922
  • Это делается не через обработчик клика, через него это просто не сделать нормально, а через команду, и MVVM здесь не при чём. – aepot Mar 26 '24 at 10:36

2 Answers2

1

Здесь всё просто сделать через команду. MVVM здесь не требуется, это не про MVVM, это про команды.

Берём класс, упрощающий взаимодействие с командами и добавляем в проект, например в файл RelayCommand.cs.

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;
public event EventHandler CanExecuteChanged
{
    add =&gt; CommandManager.RequerySuggested += value;
    remove =&gt; CommandManager.RequerySuggested -= value;
}

public RelayCommand(Action&lt;object&gt; execute, Predicate&lt;object&gt; canExecute = null)
{
    _execute = execute;
    _canExecute = canExecute;
}

public bool CanExecute(object parameter) =&gt; _canExecute == null || _canExecute(parameter);
public void Execute(object parameter) =&gt; _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 не требуется.

aepot
  • 49,560
0

Если без MVVM, то присваиваем DataGrid имя: <DataGrid Name="dg" ... > и теперь в Button_Click можем получить нужную строку:

var selectedUser = dg.SelectedItem as User;

Ну а дальше из свойства получаете IP-адрес

Cost
  • 922
  • Во блин, как все просто. Спасибо!!! Осталось понять/почитать про выражение после =... – jobsdata Mar 26 '24 at 09:58
  • @jobsdata выбранная строка и строка, в которой нажата кнопка, могут отличаться, это не решение. – aepot Mar 26 '24 at 10:29
  • @aepot можете по подробней? – jobsdata Mar 26 '24 at 11:36
  • @jobsdata https://ru.stackoverflow.com/a/1116136/373567 кстати, если вам данные не надо редактировать прямо в ячейках, DataGrid - лишнее, вам больше подойдёт ListView. Но это дело вкуса. – aepot Mar 26 '24 at 12:48