18

I have a DataGrid. It has DataGrid.RowDetailsTemplate. When a button is clicked it should Expand / Collapse; how would I do that?

<Custom:DataGrid RowDetailsVisibilityMode="VisibleWhenSelected" SelectionMode="Extended" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False">
    <Custom:DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <Custom:DataGrid>
                <Custom:DataGrid.Columns>
                    <Custom:DataGridTextColumn Binding="{Binding idClient, Mode=Default}" Header="Ид" IsReadOnly="True"/>
                    <Custom:DataGridTextColumn Binding="{Binding name_client, Mode=Default}"  Header="Имя" IsReadOnly="True"/>
                </Custom:DataGrid.Columns>
            </Custom:DataGrid>
        </DataTemplate>
    </Custom:DataGrid.RowDetailsTemplate>
    <Custom:DataGrid.Columns>
        <Custom:DataGridTemplateColumn>
            <Custom:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Expander IsExpanded="True"/>
                </DataTemplate>
            </Custom:DataGridTemplateColumn.CellTemplate>
        </Custom:DataGridTemplateColumn>
        <Custom:DataGridTextColumn Binding="{Binding idPartner, Mode=Default}" Header="Ид" IsReadOnly="True"/>
        <Custom:DataGridTextColumn Binding="{Binding name_partner, Mode=Default}"  Header="Имя" IsReadOnly="True"/>
    </Custom:DataGrid.Columns>
</Custom:DataGrid>
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Mediator
  • 14,951
  • 35
  • 113
  • 191

6 Answers6

35

Check this ...

Adding a Button to a WPF DataGrid

OR

XAML :

<DataGrid Name="dg1" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="false" CanUserDeleteRows="False" SelectionUnit="FullRow" >
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
    </DataGrid.CellStyle>

    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <Expander Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">

            </Expander>
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>

    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" IsReadOnly="True" Width="100" Binding="{Binding Name}" />
        <DataGridTextColumn Header="Title" IsReadOnly="True" Width="100" Binding="{Binding Title}" />
        <DataGridTextColumn Header="Job" IsReadOnly="True" Width="100" Binding="{Binding Job}" />
    </DataGrid.Columns>

    <DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Isi, Converter={StaticResource ResourceKey=isiTextConverter}}" Margin="10,5,0,0" />
        </DataTemplate>
    </DataGrid.RowDetailsTemplate>
</DataGrid>

MainWindow.xaml.cs

private void Expander_Expanded(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;
    }
}

private void Expander_Collapsed(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;
        }
}

Output

enter image description here

Community
  • 1
  • 1
  • 4
    btw, `Expander_Expanded` and `Expander_Collapsed` are identical. if it is intended, there can be a single method to handle `Expanded` and `Collapsed` events – ASh May 10 '16 at 07:51
  • 1
    I agree with @ASh also one doesn't have to work the tree...see my answer below which answers/updates those things. – ΩmegaMan Dec 18 '19 at 14:47
  • 1
    What's missing from this answer is setting `RowDetailsVisibilityMode` for the data grid to `DataGridRowDetailsVisibilityMode.Collapsed`. Otherwise both the expander and the data grid expand the rows. And data grid does that on any row click, not only when clicking the expander. – BartoszKP Aug 03 '20 at 19:15
2

Instead of walking the tree to find the datagrid row from the expander, use the static method GetRowContainingElement which is found on DataGridRow. Such as:

private void Expander_Process(object sender, RoutedEventArgs e)
{
    if (sender is Expander expander)
    {
        var row = DataGridRow.GetRowContainingElement(expander);

        row.DetailsVisibility = expander.IsExpanded ? Visibility.Visible 
                                                    : Visibility.Collapsed;
    }
}

Then the expander has only one method call for each of the events:

 <Expander Expanded="Expander_Process"  Collapsed="Expander_Process" />
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
1

Include Collapsed and expanded events as below

   <Custom:DataGridTemplateColumn>
   <Custom:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Expander Collapsed="exp_Collapsed" Expanded="exp_Expanded"/>
            </DataTemplate>
        </Custom:DataGridTemplateColumn.CellTemplate>
    </Custom:DataGridTemplateColumn>

In the code behind

 private void exp_Collapsed(object sender, RoutedEventArgs e)
        {
            this.dataGrid1.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Collapsed;
        }

        private void exp_Expanded(object sender, RoutedEventArgs e)
        {
            this.dataGrid1.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
        }
Perchik
  • 5,262
  • 1
  • 19
  • 22
Bindya
  • 135
  • 2
  • 14
  • 1
    The act of selecting a row opens it up. By doing your call to collapse will collapse all rows regardless of whether the row is selected or not. – ΩmegaMan Dec 18 '19 at 14:53
1

I have improved the previous answer :

Instead of using DataGrid.RowHeaderTemplate use DataGridTemplateColumn as below:

<DataGridTemplateColumn>
   <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
                <Expander Expanded="Expander_OnExpanded"     Collapsed="Expander_OnCollapsed">
                </Expander>
           </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Benifit is you need not to re position your mouse after clicking expander button.

Palash Roy
  • 1,547
  • 1
  • 15
  • 11
  • Not sure what you mean by repositioning the mouse. Updated answer below. – ΩmegaMan Dec 18 '19 at 14:52
  • @ΩmegaMan, I mean that the position of expander button does not change, thus need not to move mouse pointer up/down to further click on expander button. Thanks. – Palash Roy Jan 22 '20 at 18:01
1

Selecting a Row on the Grid should expand the Row using the RowDetailsTemplate to display the content. This makes that Row the Selected Row and sets the value of the DataGrid's SelectedIndex Property.

To collapse the Row set the DataGrid's SelectedIndex Property to -1.

Paul Lydon
  • 958
  • 6
  • 6
0

ΩmegaMan answer works great! Don`t forget to add:

 <DataGrid x:Name="DGrid" RowDetailsVisibilityMode="Collapsed"/>
John
  • 3
  • 3