Indenting column data in hierarchical data in the XamDataGrid

Before I start this post, let me just say I’m using an old version of the Infragistics XamDataGrid for this post, version 10.3. Hence this may have been changed in subsequent releases, but as I have a legacy application to support, that’s the version they’re using.

So in my previous blog posts on displaying hierarchical data within the XamDataGrid I demonstrated how to get the grid to look a little like a tree view, i.e. show the data in aligned columns etc. but I also mentioned that it wasn’t yet good enough as the child nodes are not indented.

So let’s look at how we might indent the child nodes so that they look more like a tree view and differentiate between child nodes and parent nodes.

What we want to do is change this

Before indentation

to this

After indentation

Here’s a reminder of how our XAML looked at the end of the previous post

<igDP:XamDataGrid DataSource="{Binding}" GroupByAreaLocation="None" x:Name="grid"
   FieldPositionChanged="Grid_OnFieldPositionChanged">
   <igDP:XamDataGrid.Resources>
      <Style TargetType="{x:Type igDP:LabelPresenter}">
         <EventSetter Event="SizeChanged" Handler="EventSetter_OnHandler"/>
      </Style>
   </igDP:XamDataGrid.Resources>

   <igDP:XamDataGrid.FieldLayoutSettings>
      <igDP:FieldLayoutSettings ExpansionIndicatorDisplayMode="CheckOnDisplay"
         AutoGenerateFields="False"/>
   </igDP:XamDataGrid.FieldLayoutSettings>
   <igDP:XamDataGrid.FieldLayouts>

      <igDP:FieldLayout Key="parent">
         <igDP:FieldLayout.Fields>
            <igDP:Field Name="Name" />
            <igDP:Field Name="Manages" Visibility="Hidden" />
         </igDP:FieldLayout.Fields>
      </igDP:FieldLayout>

      <igDP:FieldLayout Key="child">
         <igDP:FieldLayout.Settings>
            <igDP:FieldLayoutSettings LabelLocation="Hidden" 
                 DataRecordPresenterStyle="{StaticResource childDataRecordStyle}"/>
         </igDP:FieldLayout.Settings>
         <igDP:FieldLayout.Fields>
            <igDP:Field Name="Name"/>
             <igDP:Field Name="Manages" Visibility="Hidden" />
         </igDP:FieldLayout.Fields>
      </igDP:FieldLayout>

   </igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>

We’ve already used a value converter once, to align the columns, we’re going to use the same technique now to indent our cell data. Here’s the convert code

public class ChildCellValueConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      return value == null ? Binding.DoNothing : new Thickness((((int)value / 2) * 17), 0, 0, 0);
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}

Now let’s implement the resource code in XAML

<controls:ChildCellValueConverter x:Key="childCellValueConverter" />

<Style x:Key="childCellValueStyle" TargetType="{x:Type igDP:CellValuePresenter}">
   <Setter Property="Margin" Value="{Binding NestingDepth, Converter={StaticResource childCellValueConverter}}"/>
</Style>

and finally we need to update the field layout (for the “child”) to add the following (within the Field “Name” element

<igDP:Field.Settings>
   <igDP:FieldSettings CellValuePresenterStyle="{StaticResource childCellValueStyle}" />
</igDP:Field.Settings>

and there we have it. Now the child records indent.

Note: Unfortunately the solution to displaying the child nodes offset from the parent nodes is not perfect. You may notice white space where text should be for some rows. If I come up with a solution I’ll update this post accordingly.