Silverlight / WPF - hierarchical datagrid - Asked By D N C on 17-Oct-11 10:22 AM

Hello all,

I was earlier looking fora way to build a hierarchical datagrid that groups the rows based on one of the column values..
With some of your suggestions and the help of the following links i had built a hierarchical datagrid.
www.Wpftutorial.com and http://blog.smoura.com/wpf-toolkit-datagrid-part-iv-templatecolumns-and-row-grouping/

Now that i have achieved 50% of the requirement, i need your help to improve my grid.

this is how the datagrid looks.
the improvement needed is the expander header is empty but i want it to display the first row of the grouped elements and the rows that are not grouped should not have an expander.

how do i achieve it?

The Xaml goes as follows

<CollectionViewSource x:Key="Details">

<CollectionViewSource.GroupDescriptions>

<PropertyGroupDescription PropertyName="Column1"/>

</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>



<DataGrid.GroupStyle>

<GroupStyle>

<GroupStyle.ContainerStyle>

<Style TargetType="{x:Type GroupItem}">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type GroupItem}">

<Expander>

<Expander.Header>

<StackPanel Orientation="Horizontal">

<TextBlock>

<TextBlock.Text>

<Binding Path="Column1"/>

</TextBlock.Text>

</TextBlock>

</StackPanel>

</Expander.Header>

<ItemsPresenter />

</Expander>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</GroupStyle.ContainerStyle>

</GroupStyle>

</DataGrid.GroupStyle>

The code behind is this:

Public Sub New()

' This call is required by the designer.

InitializeComponent()

Dim VM As New ViewModel()

Dim Details As New ObservableCollection(Of tablename)

Details = VM.AllDetails

Dim collection As New ListCollectionView(Details)

collection.GroupDescriptions.Add(New PropertyGroupDescription("Column1"))

dtgShipments.ItemsSource = collection

Dim Column1 As String

Column1 = VM.Column1  

' Add any initialization after the InitializeComponent() call.

End Sub

Please helppppp :)

Please helppppp :)

Sri K replied to D N C on 30-Oct-11 11:45 AM

Using RowDetailsTemplate might be useful to implement nested datagrids.

For example, your normal datagrid might look like this.

<data:DataGrid Name="ParentDG" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
    <data:DataGrid.Columns>
      <data:DataGridTextColumn Header="<<ColumnInfo>>" Binding="{Binding <<BindingInfo>>}" IsReadOnly="True" />
      ... 
    </data:DataGrid.Columns>
    <data:DataGrid.RowDetailsTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <data:DataGrid Name="NestedDG"></data:DataGrid>
        </StackPanel>
      </DataTemplate>
    </data:DataGrid.RowDetailsTemplate>
</data:DataGrid>

Note that the RowDetailsVisibilityMode is set to "VisibleWhenSelected". Thus, whenever you click on a row in the datagrid, the content of rowdetailstemplate is displayed.

The only plumbing left now is to set the datasource of the inner-grid. You can do that by following these steps:
1. Create an event handler for "RowDetailsVisibilityChanged" event
    ParentDG.RowDetailsVisibilityChanged += new EventHandler<DataGridRowDetailsEventArgs>(ParentDG_RowDetailsVisibilityChanged);

2. Define the event handler to set the data-source for the inner-grid.
   void ParentDG_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
   {
    DataGrid nestedGrid = (DataGrid)e.DetailsElement.FindName("NestedDG");
      if (e.Row.DetailsVisibility == Visibility.Visible)
      {
        nestedGrid.ItemsSource = <<Set the item source for the nested grid here>>;
      }
    }

Note that we obtian the nested grid from the DetailsElement and set the item source for the nested datagrid.

I implemented it for Customer-Orders scenario in Northwind database.

Hope this answers your question.