我只是想在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工具发现了这个,但是我无法分辨它的含义,我发现没有其他红线也没有进入绑定错误列。
答案 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.Items
或TreeViewItem.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"));
}
// ...
}