Skip to content

implement TreeDataGrid #3877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

MohammadHadi2031
Copy link
Contributor

@MohammadHadi2031 MohammadHadi2031 commented Jun 23, 2025

Hi Keboo.

According to talk in the discord about adding columns to TreeListView I created this pull request. This is WIP and most of the task is done just the styles is left (light/dark theme, ...). for using this just run demo app and go to trees -> multi select tree view I have couple of questions:

  1. Shall we show gripper (gridlines) for columns? in material design theme the data table column's gripper has no color.
  2. In order to show columns for cells I used GridViewRowPresenter but I can't remove internal:TreeListViewContentPresenter because no children is shown. so the final code is as below. Is there better solution for this?
 <Grid Margin="0,0,0,0">
   <internal:TreeListViewContentPresenter x:Name="PART_ContentPresenter"
                                          Content="{TemplateBinding Content}"
                                          Visibility="Hidden" />

   <GridViewRowPresenter x:Name="PART_Header"
                         Columns="{Binding Columns, RelativeSource={RelativeSource AncestorType={x:Type wpf:TreeListView}}}"
                         Content="{TemplateBinding Content}" />
 </Grid>
  1. For showing gridlines for each treelistview cells I created simple TreeListViewCell if it's not necessary to show gridlines we can remove this.
 <Style TargetType="{x:Type wpf:TreeListViewCell}">
   <Setter Property="Template">
     <Setter.Value>
       <ControlTemplate TargetType="{x:Type wpf:TreeListViewCell}">
         <Border Background="{TemplateBinding Background}"
                 BorderBrush="{TemplateBinding BorderBrush}"
                 BorderThickness="{TemplateBinding BorderThickness}">
           <Grid>
             <Border Margin="0,0,-5,0"
                     Padding="0,3,0,3"
                     HorizontalAlignment="Stretch"
                     VerticalAlignment="Stretch"
                     BorderBrush="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:TreeListViewItem}}, Path=IsSelected, Converter={StaticResource TreeListViewGridLineBrushConverter}}"
                     BorderThickness="0,0,1,0">
               <TextBlock Text="" />
             </Border>

             <ContentPresenter />
           </Grid>
         </Border>
       </ControlTemplate>
     </Setter.Value>
   </Setter>
 </Style>
  1. I moved Toggle button to the first column data template this is a easy trick but maybe not perfect solution I want to ask you what could be better way to have toggle button on the first cell. here is the first column
<GridViewColumn Width="250"
                Header="Name">
  <GridViewColumn.CellTemplate>
    <DataTemplate>
      <materialDesign:TreeListViewCell>
        <StackPanel Orientation="Horizontal">
          <StackPanel.Margin>
            <MultiBinding Converter="{StaticResource TreeListViewIndentConverter}">
              <Binding Path="LevelIndentSize"
                       RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type materialDesign:TreeListView}}" />
              <Binding Path="Level"
                       RelativeSource="{RelativeSource AncestorType={x:Type materialDesign:TreeListViewItem}}" />
            </MultiBinding>
          </StackPanel.Margin>

          <ToggleButton IsChecked="{Binding RelativeSource={RelativeSource AncestorType=materialDesign:TreeListViewItem, Mode=FindAncestor}, Path=IsExpanded}"
                        Style="{StaticResource MaterialDesignTreeListViewToggleButtonStyle}" />

          <TextBlock VerticalAlignment="Center"
                     Text="{Binding Name, Mode=OneTime}" />
        </StackPanel>
      </materialDesign:TreeListViewCell>
    </DataTemplate>
  </GridViewColumn.CellTemplate>
</GridViewColumn>
  1. Can I create new control called TreeDataGrid?

feel free to mention me if there is any error. here is my view
image

@Keboo Keboo self-requested a review June 23, 2025 15:22
@Keboo
Copy link
Member

Keboo commented Jun 27, 2025

Just replying back to the questions.

  1. I think let's skip on the separator line. I think having it similar to the DataGrid is probably most common.
  2. This is a bit interesting and will require some more thought. Initially I think it might be fine, but I am interested in testing out some cases with template bindings as that was the intent for in the other presenter.
  3. Yea I think we can drop it (as per 1)
  4. This is more interesting, I would really want to keep the toggle outside of the columns.
  5. I am bit hesitant to create a brand-new control. I would be more open to a new control template over the existing one though. It seems like that might be the cleaner approach.

I think we might need to pivot on the implementation a bit here. It would probably be better to look more at implementing it view the GridView similar to how the WPF base ListView control works. This likely will be a more complicated path, but I think it will be the better approach.

@MohammadHadi2031
Copy link
Contributor Author

MohammadHadi2031 commented Jun 27, 2025

Thanks a lot for suggesting GridView it got much easier but still toggle button is the issue. So what I did was to see how WPF is working with GridView and I found out that for having columns it uses style for the ScrollViewer and for having cells in rows it uses GridViewRowPresenter too. So we have it columns and cells. the only thing is to support both TreeListView.View == null and TreeListView.View != null I've done it with a simple DataTrigger just like how WPF does.

<DataTrigger Binding="{Binding View, RelativeSource={RelativeSource AncestorType=wpf:TreeListView}, Converter={StaticResource ViewIsGridViewConverter}}" Value="True">
    <Setter TargetName="PART_ContentPresenter" Property="Visibility" Value="Hidden" />
    <Setter TargetName="PART_GridViewRowPresenterr" Property="Visibility" Value="Visible" />
</DataTrigger>

image

The only problem is the ToggleButton outside the TreeListViewItem causes tests to fail. I'm working on it

@MohammadHadi2031
Copy link
Contributor Author

Hi. The toggle button is now automatically added to the first column. I commented out the assignment of TreeListView.View to make the tests pass.

@MohammadHadi2031
Copy link
Contributor Author

I think we can remove this comment after merging #3875

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants