在TreeView

时间:2015-07-06 09:36:39

标签: wpf .net-4.0 treeview hierarchicaldatatemplate

我只是想在TreeView中显示分层数据,但我无法弄清楚如何让它显示超过前两个级别。 (而且我已经阅读了几乎令人难忘的TreeView帖子,也许问题是我(错过)在这种情况下低估了Bindings)

我已经简化了我的数据结构测试:

public class Node
{
    public List<Node> Children { get; set; }

    public Node Parent { get; set; }

    public string Expression { get; set; }
}

Xaml目前看起来像这样:(请注意我现在已多次更改它,但这是我提出的原始状态:)

<Window x:Class="Klammern_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Klammern_Test"
        Title="MainWindow" Height="439" Width="402">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Node}">
            <TreeViewItem ItemsSource="{Binding Children}" Header="{Binding Expression}"/>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView ItemsSource="{Binding Root}" Margin="12,41,12,12" Name="treeView" />            
    </Grid>
</Window>

这就是我尝试填充树视图的方式:

public partial class MainWindow : Window
{
        public Node Root { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            Parser = new StringParser();
            Root = Parser.Parse(Tbx_Eingabe.Text);       
            treeView.Items.Add(PopulateTreeView(Root));



        }

        private TreeViewItem PopulateTreeView(Node node)
        {
            TreeViewItem treeViewItem = new TreeViewItem();
            treeViewItem.IsExpanded = true;
            treeViewItem.Header = node.Expression;


            foreach (Node child in node.Children)
            {
                treeViewItem.Items.Add(new TreeViewItem() { Header = child.Expression });

                if (child.Children.Count > 0)
                {
                    PopulateTreeView(child);
                }
            }

            return treeViewItem;
        }
}

我错过了什么?

编辑:

在尝试了almulo的提示之后,我用Snoop工具发现了这个,但是我无法分辨它的含义,我发现没有其他红线也没有进入绑定错误列。

Snoop screenshot of potential binding Error

1 个答案:

答案 0 :(得分:1)

TreeViewItem内使用HierarchicalDataTemplate,这是TreeView的TreeViewItems用来创建自己的东西......令人困惑。

HierarchicalDataTemplate内,你应该添加你想要项目“标题”的控件。在这种情况下,我想它应该是TextBlock,因为你只想显示一些文字。

然后使用HierarchicalDataTemplate.ItemSource属性绑定节点的子节点。

    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Node}" 
                                  ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Expression}" />
        </HierarchicalDataTemplate>
    </Window.Resources>

此外,在您的代码隐藏中,您不应直接操纵TreeView.ItemsTreeViewItem.Items,因为您已经在使用Bindings和ItemsSource属性。

相反,请删除PopulateTreeView方法,并让您的Root属性作为TreeView的项目源。但为了使其正常工作,您必须在Root属性更改其值时通知视图。

为此,请执行INotifyPropertyChanged界面并在每次PropertyChanged更改时触发Root事件。

编辑: ItemsControl属性ItemsSource需要一个集合(更具体地说是IEnumerable),因此Root需要为一个。即使它只有一个项目,如下所示:

public class MainWindow : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    // ...

    private void StartButton_Click(object sender, RoutedEventArgs e)
    {
        Parser = new StringParser();
        Root = new Node[] { Parser.Parse(Tbx_Eingabe.Text) };

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Root"));
    }

    // ...
}