Search code examples
c#wpfwpfdatagrid

Expand/Collapse of a nested WPF Grid


I have created a nested WPF Datagrid. I see you can expand it by clicking on the row, but it doesn't collapse when you do the same thing.

Few questions:

  1. How can the user collapse the grid?
  2. Is there a way to get Expand/Collapse buttons on the parent rows?
  3. Whenever you click on a different parent to expand, it collapses the previous one you are on. Is there a way to get the grid to stay the way you make it. i.e. If I expand row 1 then go to row 3, row 1 will stay where I expanded it to.

Thanks, Greg


Solution

  • There are couple approaches to reach such behavior. For example Expand/Collapse button in a Silverlight DataGrid.

    If you prefer xaml then use:

    <Style x:Key="ExpandableDataGridRowHeaderStyle"
               TargetType="sdk:DataGridRowHeader">
        <Setter Property="Background"
                    Value="#99E9EEF4" />
        <Setter Property="IsTabStop"
                    Value="False" />
        <Setter Property="SeparatorBrush"
                    Value="#FFFFFFFF" />
        <Setter Property="SeparatorVisibility"
                    Value="Collapsed" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="sdk:DataGridRowHeader">
                    <Grid x:Name="Root">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="25" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>                           
                        <Border BorderBrush="#FFFFFFFF"
                                    BorderThickness="1,0,1,0"
                                    Grid.ColumnSpan="2"
                                    Grid.RowSpan="3">
                            <Grid>
                                <Rectangle x:Name="RowInvalidVisualElement"
                                               Grid.ColumnSpan="2"
                                               Fill="#FFF7D8DB"
                                               Opacity="0"
                                               Grid.RowSpan="3"
                                               Stretch="Fill" />
                                <Rectangle x:Name="BackgroundRectangle"
                                               Grid.ColumnSpan="2"
                                               Fill="Transparent"
                                               Grid.RowSpan="3"
                                               Stretch="Fill" />
                            </Grid>
                        </Border>
                        <Button Background="{x:Null}"
                                    BorderBrush="{x:Null}"
                                    BorderThickness="0"
                                    Padding="0"
                                    Grid.RowSpan="1"
                                    HorizontalAlignment="Stretch">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Click">
                                    <AttachedBehaviors:ExpandButtonAction/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </Button>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    And AttachedBehavior that actually will change DetailsVisibility:

    public class ExpandButtonAction : TargetedTriggerAction<FrameworkElement>
    {
        #region Invoke
    
        protected override void Invoke(object parameter)
        {
            RoutedEventArgs eventArgs = (RoutedEventArgs) parameter;
            Button bsender = eventArgs.OriginalSource as Button;
            var row = DataGridRow.GetRowContainingElement(eventArgs.OriginalSource as FrameworkElement);
            if (row.DetailsVisibility == Visibility.Visible)
            {
                row.DetailsVisibility = Visibility.Collapsed;
            }
            else
            {
                row.DetailsVisibility = Visibility.Visible;
            }
        }
    
        #endregion
    }
    

    And apply this for RowHeaderStyle of DataGrid where you want to expand/collapse DetailsTemplate.