Button in a column, getting the row from which it came on the Click event handler

C#WpfXamlDatagridDatagridview

C# Problem Overview


I've set the itemsource of my WPF Datagrid to a List of Objects returned from my DAL. I've also added an extra column which contains a button, the xaml is below.

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

This renders fine. However on the Button_Click method, is there any way I can get the row on the datagrid where the button resides? More specifically, one of the properties of my objects is "Id", and I'd like to be able to pass this into the constructor of another form in the event handler.

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

Perhaps I need something extra in my xaml, or maybe I'm going about this in a roundabout way? Any help/advice appreciated.

C# Solutions


Solution 1 - C#

Basically your button will inherit the datacontext of a row data object. I am calling it as MyObject and hope MyObject.ID is what you wanted.

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

Solution 2 - C#

Another way I like to do this is to bind the ID to the CommandParameter property of the button:

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

Then you can access it like so in code:

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

Solution 3 - C#

Another way which binds to command parameter DataContext and respect MVVM like Jobi Joy says button inherits datacontext form row.

Button in XAML

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

Command implementation

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

Solution 4 - C#

MyObject obj= (MyObject)((Button)e.Source).DataContext;

Solution 5 - C#

If your DataGrid's DataContext is a DataView object (the DefaultView property of a DataTable), then you can also do this:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRekrowYnapmocView Question on Stackoverflow
Solution 1 - C#Jobi JoyView Answer on Stackoverflow
Solution 2 - C#xr280xrView Answer on Stackoverflow
Solution 3 - C#Petr ŠebestaView Answer on Stackoverflow
Solution 4 - C#ShihaView Answer on Stackoverflow
Solution 5 - C#SurfingSantaView Answer on Stackoverflow