wpf : Hierarchical data in a datagrid

Anthony Harel 21 Reputation points
2021-11-26T07:17:50.893+00:00

Hi,

I have a hierarchical data structure that I would like to display in a grid.

152852-capture.jpg

I have a list of functions and each function in the list contains a list of parameters and I would like to display this list of functions in a grid like above.
What is the best graphics component to do this? A Datagrid, a TreeListView?
And especially how to bind my data on this component?
I'm having a lot of trouble ...

Does anyone among you have a similar example to submit to me?

Thanks

Developer technologies Windows Presentation Foundation
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2021-11-27T20:14:14+00:00

    Hi Anthony,
    you can use additional list for view like in following demo.

    XAML:

    <Window x:Class="Window099"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp099"  
            mc:Ignorable="d"  
            Title="Window099" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
        <DataGrid ItemsSource="{Binding View}" AutoGenerateColumns="False" CanUserAddRows="false">  
          <DataGrid.Columns>  
            <DataGridTextColumn Header="Nr." Binding="{Binding Nr}"/>  
            <DataGridTextColumn Header="Fuction" Binding="{Binding Funk}"/>  
            <DataGridTemplateColumn Header="Parameter">  
              <DataGridTemplateColumn.CellTemplate>  
                <DataTemplate>  
                  <TextBlock Text="{Binding Par}"/>  
                </DataTemplate>  
              </DataGridTemplateColumn.CellTemplate>  
            </DataGridTemplateColumn>  
            <DataGridTemplateColumn Header="Value">  
              <DataGridTemplateColumn.CellTemplate>  
                <DataTemplate>  
                    <TextBlock Text="{Binding ParValue}"/>  
                </DataTemplate>  
              </DataGridTemplateColumn.CellTemplate>  
            </DataGridTemplateColumn>  
          </DataGrid.Columns>  
        </DataGrid>  
      </Grid>  
    </Window>  
    

    and classes:

    Imports System.Collections.ObjectModel  
    Imports System.ComponentModel  
      
    Namespace WpfApp099  
      
      Public Class ViewModel  
      
        ' generate demo data  
        Public Sub New()  
          For i = 1 To 20  
            Dim d As New Data1 With {.Nr = i, .Funk = $"Function {i}"}  
            If rnd.NextDouble < 0.5 Then  
              d.Functions.Add(New Data2 With {.Par = "X", .ParValue = rnd.Next(10, 100).ToString})  
              If rnd.NextDouble < 0.6 Then  
                d.Functions.Add(New Data2 With {.Par = "Y", .ParValue = rnd.Next(10, 100).ToString})  
                If rnd.NextDouble < 0.7 Then  
                  d.Functions.Add(New Data2 With {.Par = "Z", .ParValue = rnd.Next(10, 100).ToString})  
                End If  
              End If  
            End If  
            col.Add(d)  
          Next  
        End Sub  
      
        Private rnd As New Random  
        Private col As New ObservableCollection(Of Data1)  
        Private cvs As New CollectionViewSource  
      
        ' convert demo data to viewed data  
        Public ReadOnly Property View As ICollectionView  
          Get  
            Dim col3 As New ObservableCollection(Of Data3)  
            cvs.Source = col3  
            For Each d1 In col  
              Dim d As New Data3 With {.Nr = d1.Nr.ToString, .Funk = d1.Funk}  
              If d1.Functions.Count > 0 Then  
                d.Par = d1.Functions(0).Par  
                d.ParValue = d1.Functions(0).ParValue  
              End If  
              col3.Add(d)  
              For i = 1 To d1.Functions.Count - 1  
                col3.Add(New Data3 With {.Par = d1.Functions(i).Par, .ParValue = d1.Functions(i).ParValue})  
              Next  
            Next  
            cvs.Source = col3  
            Return cvs.View  
          End Get  
        End Property  
      End Class  
      
      Public Class Data1  
        Public Property Nr As Integer  
        Public Property Funk As String  
        Public Property Functions As New List(Of Data2)  
      End Class  
      
      Public Class Data2  
        Public Property Par As String  
        Public Property ParValue As String  
      End Class  
      
      Public Class Data3  
        Public Property Nr As String  
        Public Property Funk As String  
        Public Property Par As String  
        Public Property ParValue As String  
      End Class  
      
    End Namespace  
    

    Result:

    153073-x.png

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.