Adding a Button to a WPF DataGrid
Asked Answered
C

4

70

I want to create a DataGrid control in WPF in which there is a button in the first cell of each row. Clicking this button will show RowDetailsTemplate or the SubRow.

How do I add a button which will show/Hide the RowDetailsTemplate?

Crowberry answered 15/6, 2010 at 14:15 Comment(0)
A
95

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;
    }
}
Agnew answered 16/6, 2010 at 0:22 Comment(3)
This adds the button in first column, any idea for last column?Nuri
@Hassan Ansari This adds the button wherever you put it. If you put the XAML I show above before your other columns, the button will appear as the first column. If you put the XAML after all your other columns, the button will appear as the last column. If you put it in the middle, the button will show in the middle. You can put your columns in any order, and the button can be in any column.Agnew
My Columns are autogenerated and I'm getting data in columns as datagrid.itemSource = List<MyEntity>Nuri
S
36

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;
Sixtyfourmo answered 15/6, 2010 at 16:7 Comment(1)
This seems to have nothing to do with the question, which was about how to show/hide detail rows when a button is clicked. What this code does is cause some data in the model to change when a button is clicked.Agnew
D
4

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.

Defalcate answered 3/12, 2018 at 15:44 Comment(0)
S
3

If you want to use a Command instead, you can use the example below as basement.

<DataGridTemplateColumn
Header="Action"
>
<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Button 
            VerticalAlignment="Top"
            Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource FindAncestor, 
                AncestorLevel=1, AncestorType={x:Type UserControl}}}" 
            CommandParameter="{Binding .}"
            Content="Delete">                
        </Button>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

Check if your AncestorTyp matches the parent view where your ViewModel is bound.

Sheikh answered 10/4, 2023 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.