Кнопка в стовпці, отримуючи рядок, з якого вона вийшла на обробник подій Click


97

Я встановив предметний ресурс моєї WPF Datagrid до списку об'єктів, повернених з мого DAL. Я також додав додатковий стовпчик, який містить кнопку, xaml внизу.

<toolkit:DataGridTemplateColumn  MinWidth="100" Header="View">
    <toolkit:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Click="Button_Click">View Details</Button>
        </DataTemplate>
    </toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>

Це призводить до штрафу. Однак у методі Button_Click чи є спосіб отримати рядок на сітці даних, де знаходиться кнопка? Більш конкретно, одним із властивостей моїх об'єктів є "Id", і я хотів би мати можливість передати це в конструктор іншої форми в обробці подій.

private void Button_Click(object sender, RoutedEventArgs e)
    {
        //I need to know which row this button is on so I can retrieve the "id"  
    }

Можливо, мені потрібне щось додаткове в моєму xaml, або, можливо, я буду про це в обхідному напрямку? Будь-яка допомога / рада оцінена.

Відповіді:


128

В основному ваша кнопка буде успадковувати контекст даних об’єкта рядкових даних. Я називаю це MyObject і сподіваюся, що MyObject.ID - те, чого ви хотіли.

private void Button_Click(object sender, RoutedEventArgs e)
{
    MyObject obj = ((FrameworkElement)sender).DataContext as MyObject;
    //Do whatever you wanted to do with MyObject.ID
}

7
Ідеальний спосіб зробити подібний матеріал - це використання команд (в основному MVVM-шаблон), ви можете створити команду у вашому об’єкті даних (ViewModel) та викликати Button.Command, щоб не було ніякого коду позаду, як натискання кнопки.
Jobi Joy

1
@JobiJoy: чи є у вас приклад цього за допомогою команди Command / RelayCommand? Я намагаюся декілька речей, але не можу змусити його працювати.
VoodooChild

Проблема з прикладами команд, які я бачив, полягає в тому, що вам потрібно пов’язати вибраний елемент datagrid з членом вашої моделі перегляду, і тому важко загальнокомандувати команду достатньо, щоб бути хорошою для кнопки видалення. Я хочу один ресурс стовпчика шаблону кнопки видалення, який я можу використовувати, щоб видалити майже все, що в моєму додатку.
Ерік

47

Ще один спосіб мені подобається зробити це - прив’язати ідентифікатор до властивості CommandParameter кнопки:

<Button Click="Button_Click" CommandParameter="{Binding Path=ID}">View Details</Button>

Тоді ви можете отримати доступ до нього так у коді:

private void Button_Click(object sender, RoutedEventArgs e)
{
    object ID = ((Button)sender).CommandParameter;
}

Чому ви змішуєте події та команди? Використовуйте команду Command та використовуйте в ній параметр команди.
ПрофК

1
3 відповіді: Чому ні? Простота. І ОП запитує про обробників подій, а не про команди. Команда може бути зайвою. Використання CommandParameterможе бути не цільовим призначенням властивості, але семантично, це більш значуще, ніж використання Tagта простіше, ніж отримання ідентифікатора із пов'язаного об'єкта в обробнику. Якщо ви віддаєте перевагу командам, такий підхід чудово, але навіщо додавати складність, якщо ви не збираєтесь його використовувати?
xr280xr

10

Ще один спосіб, який пов'язує командний параметр DataContext і поважає MVVM, як говорить Джобі Джой, кнопка успадковує рядок форми даних.

Кнопка в XAML

<RadButton Content="..." Command="{Binding RowActionCommand}" 
                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"/>

Реалізація команди

public void Execute(object parameter)
    {
        if (parameter is MyObject)
        {

        }
    }

Отже, чи буде RowActionCommand у моделі, чи ви скинули б контекст даних кнопки на ViewModel?
Том Паділья

@ PetrŠebesta "RowActionCommand визначається у кожній моделі перегляду рядків." Це не має сенсу. Але все одно, приємне рішення.
Ігор


0

Якщо DataCridtext вашого DataGrid є об’єктом DataView (властивість DefaultView DataTable), ви також можете зробити це:

private void Button_Click(object sender, RoutedEventArgs e) {
   DataRowView row = (DataRowView)((Button)e.Source).DataContext;
}

Це повинно бути e.OriginalSource. замість e.Source.
Bigeyes

Серйозно Bigeyes, моя відповідь з реального, живого, робочого коду!
SurfingSanta
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.