在WPF中将TreeViewItem显示为网格行

12

基本上,我需要使用WPF的TreeView控件实现像这样的效果:(随机图片)


(来源:msdn.com

其中节点和子节点具有相同的标题。

我进行了很多搜索,但我的WPF知识不是很好。

这是我的父节点类:

 public class Parent : PropertyChangedBase
    {
        public string ParentName { get; set; }
        public BindableCollection<Child> Children { get; set; }
    }

孩子:

public class Child : PropertyChangedBase
{
    public string ChildName { get; set; }
}

我的XAML树视图:

  <TreeView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Nodes}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type projectModels:Parent}" ItemsSource="{Binding Children}">
                <StackPanel>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <CheckBox Grid.Column="2"></CheckBox>
                        <TextBlock Grid.Column="1" Text="{Binding ParentName}">
                        </TextBlock>
                    </Grid>
                </StackPanel>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type projectModels:Child}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding ChildName}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </TreeView.Resources>
    </TreeView>

我尝试使用Grid,但显然会创建不同的网格,所以我可以依赖列宽。

我尝试了如何在wpf应用程序中使gridview成为treeview的子元素,但他们使用ListView。对我来说现在不是一个选项,因为treeviewitem选择功能与我的treeview和代码紧密耦合。

有什么想法怎么做吗?谢谢。


除了每个项目中列宽不同的问题,您的<Grid>代码是否正常工作? - Andrew Stephens
是的,它可以工作,但不是我需要的方式。我需要树形视图和其子节点的公共标题。这样我就可以调整它们的大小,并使节点的宽度相同。 - makambi
2个回答

21

试试这个 xaml

  <TreeView x:Name="treeviewList"  ItemsSource="{Binding ManufacturerList}">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <TreeViewItem  ItemsSource="{Binding Models}">
                <TreeViewItem.Header>
                    <Grid Width="350">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100"></ColumnDefinition>
                            <ColumnDefinition Width="Auto" MinWidth="50"></ColumnDefinition>
                            <ColumnDefinition ></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Task}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0"/>
                        <TextBlock Text="{Binding durationTotal}" Margin="10,0,10,0" HorizontalAlignment="Left" VerticalAlignment="Center"  Grid.Column="1"/>
                        <TextBlock Text="{Binding HeadNote}" HorizontalAlignment="Left"  VerticalAlignment="Center"  Grid.Column="2"/>
                    </Grid>
                </TreeViewItem.Header>
                <TreeViewItem.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="-20,0,0,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="100"></ColumnDefinition>
                                <ColumnDefinition Width="Auto" MinWidth="50"></ColumnDefinition>
                                <ColumnDefinition></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="{Binding SubTask}" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0"/>
                            <TextBlock Text="{Binding Duration}" Margin="10,0,10,0" HorizontalAlignment="Left" VerticalAlignment="Center"  Grid.Column="1"/>
                            <TextBlock Text="{Binding Notes}" HorizontalAlignment="Left" VerticalAlignment="Center"  Grid.Column="2"/>
                        </Grid>
                    </DataTemplate>
                </TreeViewItem.ItemTemplate>
            </TreeViewItem>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

c# 代码

public class Company
{
    public string Task { get; set; }
    public string durationTotal { get; set; }
    public string HeadNote { get; set; }
    public List<Model> Models { get; set; }
}
public class Model
{
    public string SubTask { get; set; }
    public string Duration { get; set; }
    public string Notes { get; set; }      
}

   List<Company> ManufacturerList = new List<Company>();

        ManufacturerList.Add(new Company()
        {
            Task = "Coding",
            durationTotal = "4",
            HeadNote = "Coding Task",
            Models = new List<Model>()
            {new Model(){SubTask = "Write", Duration = "2", Notes ="It pays the bills" },
            new Model(){SubTask = "Compile", Duration = "1", Notes ="c# or go home" },
            new Model(){SubTask = "Test", Duration = "1", Notes ="works on my m/c" },}
        });


        ManufacturerList.Add(new Company()
        {
            Task = "Communicate",
            durationTotal = "2",
            HeadNote = "Communicate Task",
            Models = new List<Model>()
            {new Model(){SubTask = "Email", Duration = "0.5", Notes ="so much junk mail"  },
            new Model(){SubTask = "Blogs", Duration = "0.25", Notes ="blogs.msdn.com/delay" },
            new Model(){SubTask = "Twitter", Duration = "0.25", Notes ="RT:nothing to report" },}
        });

        treeviewList.ItemsSource = ManufacturerList;

结果

在此输入图片描述


如何将固定的标题添加为数据网格列标题? - Sidso
要添加固定标题,我们可以将所有内容放在Dockpanel中,添加一个仅具有DataGridTextColumn宽度规范和x:Name="col0"的Datagrid,然后使用Width="{Binding ElementName=col0,Path=ActualWidth}"将ColumnDefinition Grid连接到彼此。参考:https://coderoad.ru/37433320/WPF-TreeView-ItemTemplate-%D0%B2%D1%8B%D1%81%D0%B0%D0%B4%D0%BA%D0%B8 - Damian Nass

7
如果你的代码唯一的问题是每个TreeView项以不同的网格列宽度呈现,你可以尝试“共享大小作用域”功能来对齐它们。在TreeView控件中,将Grid.IsSharedSizeScope设置为true:-
然后向应该在所有TreeView项上具有相同宽度的ColumnDefinition添加一个SharedSizeGroup(你的第一个列定义已经有了固定的宽度,所以在那里不需要它):-
<Grid.ColumnDefinitions>
   <ColumnDefinition Width="20" />
   <ColumnDefinition Width="Auto" SharedSizeGroup="A" />
   <ColumnDefinition SharedSizeGroup="B" />
</Grid.ColumnDefinitions>

这里的值只是用于“命名”列的字符串,可以是任何你喜欢的东西。


在TreeView控件中,将Grid.IsSharedSizeScope设置为true。没有这段代码它是无法工作的。非常感谢。 - Armen Mkrtchyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接