How to add an editable tree datagrid in C# WPF

Mojtaba_Hakim 251 Reputation points
2022-06-22T10:19:20.483+00:00

I'm using C# WPF and SQL Server Database DB first, I want to show data and edit them in Tree DataGrid , I could not find exactly what I was looking for on the internet

213784-048d8be6-4bbd-4c3a-a1a9-6e63827db145.png

How can I add this data grid model exactly like this gif in WPF?

213767-last.gif

Please introduce me a link or guide that I can find the way

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,196 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
7,036 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
559 questions
No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 14,726 Reputation points Microsoft Employee
    2022-06-23T06:28:33.823+00:00

    Hi,@Mojtaba_Hakim . Welcome Microsoft Q&A.
    Yes, you could try to collapse and expand the details.
    Xaml:

     <Window.DataContext>  
            <local:ViewModel/>  
        </Window.DataContext>  
        <Grid>  
            <DataGrid Name="dg1" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="false"   
                      CanUserDeleteRows="False" SelectionUnit="FullRow" ItemsSource="{Binding View}" >  
                <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="ID" IsReadOnly="True" Width="100" Binding="{Binding ID}" />  
                    <DataGridTextColumn Header="Name" IsReadOnly="True" Width="100" Binding="{Binding Name}" />  
                </DataGrid.Columns>  
                <DataGrid.RowDetailsTemplate>  
                    <DataTemplate>  
                        <DataGrid ItemsSource="{Binding Details}"  CanUserAddRows="True" AutoGenerateColumns="False"  
                      CanUserDeleteRows="True"  >  
                            <DataGrid.Columns>  
                                <DataGridTextColumn Header="Age" IsReadOnly="True" Width="100" Binding="{Binding Title}" />  
                                <DataGridTextColumn Header="Address" IsReadOnly="True" Width="100" Binding="{Binding Address}" />  
                            </DataGrid.Columns>  
                        </DataGrid>  
                    </DataTemplate>  
                </DataGrid.RowDetailsTemplate>  
            </DataGrid>  
        </Grid>  
    

    Codebehind:

    214212-8.txt

    Update:

     <DataGrid.RowDetailsTemplate>  
                    <DataTemplate>  
                        <DataGrid x:Name="dg" ItemsSource="{Binding Details}" Initialized="dg_Initialized"  >  
                            <DataGrid.Columns>  
                                <DataGridTextColumn Header="Age" IsReadOnly="True" Width="100" Binding="{Binding Title}" />  
                                <DataGridTextColumn Header="Address" IsReadOnly="True" Width="100" Binding="{Binding Address}" />  
                            </DataGrid.Columns>  
                        </DataGrid>  
                    </DataTemplate>  
                </DataGrid.RowDetailsTemplate>  
    

    The codebehind:

     public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject  
        {  
          if (depObj != null)  
          {  
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)  
            {  
              DependencyObject child = VisualTreeHelper.GetChild(depObj, i);  
      
              if (child != null && child is T)  
                yield return (T)child;  
      
              foreach (T childOfChild in FindVisualChildren<T>(child))  
                yield return childOfChild;  
            }  
          }  
        }  
      
        private void dg_Initialized(object sender, System.EventArgs e)  
        {  
          foreach (var datagrid in FindVisualChildren<DataGrid>(this))  
          {  
            if (datagrid.Name == "dg")  
            {  
      
              datagrid.Columns[0].Header = "MyAge";  
              datagrid.AutoGenerateColumns=false;  
              datagrid.CanUserAddRows = true;  
              datagrid. CanUserDeleteRows =true;  
      
              TextBlock x = datagrid.Columns[0].GetCellContent(datagrid.Items[2]) as TextBlock;  
              if (x != null)  
                MessageBox.Show(x.Text);  
            }  
          }  
        }  
    

    The result:
    214109-image.png


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Wafa Ibrahim Ali Asakrah 66 Reputation points
    2022-06-23T10:42:56.243+00:00

    <Window.DataContext>
    <local:ViewModel/>
    </Window.DataContext>
    <Grid>
    <DataGrid Name="dg1" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="false"
    CanUserDeleteRows="False" SelectionUnit="FullRow" ItemsSource="{Binding View}" >
    <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="ID" IsReadOnly="True" Width="100" Binding="{Binding ID}" />
    <DataGridTextColumn Header="Name" IsReadOnly="True" Width="100" Binding="{Binding Name}" />
    </DataGrid.Columns>
    <DataGrid.RowDetailsTemplate>
    <DataTemplate>
    <DataGrid ItemsSource="{Binding Details}" CanUserAddRows="True" AutoGenerateColumns="False"
    CanUserDeleteRows="True" >
    <DataGrid.Columns>
    <DataGridTextColumn Header="Age" IsReadOnly="True" Width="100" Binding="{Binding Title}" />
    <DataGridTextColumn Header="Address" IsReadOnly="True" Width="100" Binding="{Binding Address}" />
    </DataGrid.Columns>
    </DataGrid>
    </DataTemplate>
    </DataGrid.RowDetailsTemplate>
    </DataGrid>
    </Grid>

    No comments

  3. Wafa Ibrahim Ali Asakrah 66 Reputation points
    2022-06-22T20:37:02.76+00:00

    In most cases, the logical tree is a more useful representation of the elements in a WPF application. Although you do not modify the logical tree directly, this view of the application is useful for understanding property inheritance and event routing. Unlike the visual tree, the logical tree can represent non-visual data objects, such as ListItem. For more information on the logical tree, see Trees in WPF.

    The VisualTreeHelper class provides methods for returning the bounding rectangle of visual objects. You can return the bounding rectangle of a visual object by calling GetContentBounds. You can return the bounding rectangle of all the descendants of a visual object, including the visual object itself, by calling GetDescendantBounds. The following code shows how you would calculate the bounding rectangle of a visual object and all its descendants.


  4. 2022-06-23T11:43:36.23+00:00

    I think I should use DataGrid in Datagrid as per row details

    No comments