Adding a Button to a WPF DataGrid

XAML

<DataGrid x:Name="dgv_Students" AutoGenerateColumns="False" 
          ItemsSource="{Binding People}" Margin="10,20,10,0" 
          Style="{StaticResource AzureDataGrid}" FontFamily="B Yekan" 
          Background="#FFB9D1BA">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Click="RowButton_Click">Text</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

Code Behind

private IEnumerable<DataGridRow> GetDataGridRowsForButtons(DataGrid grid)
{ 
    //IQueryable
    if (!(grid.ItemsSource is IEnumerable itemsSource)) 
        yield return null;

    foreach (var item in itemsSource)
    {
        var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
        if (null != row & row.IsSelected) 
           yield return row;
    }
}

private void RowButton_Click(object sender, RoutedEventArgs e)
{
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
        if (vis is DataGridRow)
        {
           // var row = (DataGrid)vis;

            var rows = GetDataGridRowsForButtons(dgv_Students);

            string id;
            foreach (DataGridRow dr in rows)
            {
                id = (dr.Item as tbl_student).Identification_code;
                MessageBox.Show(id);
                break;
            }

            break;
        }
}

After clicking on the Button, the ID of that row is returned to you and you can use it for your Button name.


First create a DataGridTemplateColumn to contain the button:

<DataGridTemplateColumn>
  <DataGridTemplateColumn.CellTemplate> 
    <DataTemplate> 
      <Button Click="ShowHideDetails">Details</Button> 
    </DataTemplate> 
  </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn>

When the button is clicked, update the containing DataGridRow's DetailsVisibility:

void ShowHideDetails(object sender, RoutedEventArgs e)
{
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
    if (vis is DataGridRow)
    {
        var row = (DataGridRow)vis;
        row.DetailsVisibility = 
        row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        break;
    }
}

Check this out:

XAML:

<DataGrid Name="DataGrid1">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Click="ChangeText">Show/Hide</Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Method:

private void ChangeText(object sender, RoutedEventArgs e)
{
    DemoModel model = (sender as Button).DataContext as DemoModel;
    model.DynamicText = (new Random().Next(0, 100).ToString());
}

Class:

class DemoModel : INotifyPropertyChanged
{
    protected String _text;
    public String Text
    {
        get { return _text; }
        set { _text = value; RaisePropertyChanged("Text"); }
    }

    protected String _dynamicText;
    public String DynamicText
    {
        get { return _dynamicText; }
        set { _dynamicText = value; RaisePropertyChanged("DynamicText"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler temp = PropertyChanged;
        if (temp != null)
        {
            temp(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Initialization Code:

ObservableCollection<DemoModel> models = new ObservableCollection<DemoModel>();
models.Add(new DemoModel() { Text = "Some Text #1." });
models.Add(new DemoModel() { Text = "Some Text #2." });
models.Add(new DemoModel() { Text = "Some Text #3." });
models.Add(new DemoModel() { Text = "Some Text #4." });
models.Add(new DemoModel() { Text = "Some Text #5." });
DataGrid1.ItemsSource = models;