我是WPF的新手,并尝试使用treeview创建一个树。
我想要做的是动态生成树。每个treeViewItem都包含一个comboBox和一个textBlock。当用户展开节点时,应用程序将从数据源检索子节点信息。最后,用户可以使用checkBoxes选择多个节点。
在一些在线教程之后,我做了以下树:e如下所示:
<Window.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<HierarchicalDataTemplate DataType="{x:Type sotc:TaxNode}" ItemsSource="{Binding Path=Children}">
<StackPanel Orientation="Horizontal">
<CheckBox Name="chk" Margin="2" Tag="{Binding}"/>
<TextBlock Text="{Binding Path=TaxID}" ToolTip="{Binding Path=Lineage}" />
</StackPanel>
</HierarchicalDataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TreeView Margin="25,186,22,46">
<TreeViewItem Header="Taxonomy Tree" x:Name="_TaxTree" x:FieldModifier="private">
<TreeViewItem Header="Loading..." TextBlock.FontStyle="Italic"></TreeViewItem>
</TreeViewItem>
</TreeView>
</Grid>
我有一个获取所选组合框的方法
private List<CheckBox> GetSelectedCheckBoxes(ItemCollection items)
{
var list = new List<CheckBox>();
foreach (TreeViewItem item in items)
{
UIElement element = GetChildControl(item, "chk");
if (element != null)
{
var chk = (CheckBox)element;
if (chk.IsChecked.HasValue && chk.IsChecked.Value)
{
list.Add(chk);
}
}
List<CheckBox> l = GetSelectedCheckBoxes(item.Items);
list = list.Concat(l).ToList();
}
return list;
}
private UIElement GetChildControl(DependencyObject parentObject, string childName)
{
UIElement element = null;
if (parentObject != null)
{
int totalChild = VisualTreeHelper.GetChildrenCount(parentObject);
for (int i = 0; i < totalChild; i++)
{
DependencyObject childObject = VisualTreeHelper.GetChild(parentObject, i);
if (childObject is FrameworkElement &&
((FrameworkElement)childObject).Name == childName)
{
element = childObject as UIElement;
break;
}
// get its child
element = GetChildControl(childObject, childName);
if (element != null) break;
}
}
return element;
}
但是由于缺乏WPF知识,我不知道应该传递给该方法的ItemCollection是什么。
非常感谢任何建议或教程。
度过愉快的假期
答案 0 :(得分:0)
在您的XAML中,您可以向TreeView添加Name属性:
<Grid>
<TreeView Name="MyAwesomeTreeView" Margin="25,186,22,46">
<TreeViewItem Header="Taxonomy Tree" x:Name="_TaxTree" x:FieldModifier="private">
<TreeViewItem Header="Loading..." TextBlock.FontStyle="Italic"></TreeViewItem>
</TreeViewItem>
</TreeView>
</Grid>
现在,您现在可以在代码隐藏中访问此树视图中的项目,如下所示:
ItemCollection myDataItems = MyAwesomeTreeView.Items
GetSelectedCheckBoxes(myDataItems, MyAwesomeTreeView);
但是,您显示的方法不适用于带有数据模板的TreeView。原因是TreeView只有在屏幕上实际可见时才会生成TreeViewItems。在此之前,它只包含基础数据。要解决这个问题,您需要使用TreeView的ItemContainerGenerator。将复选框方法修改为:
private List<CheckBox> GetSelectedCheckBoxes(ItemCollection items, ItemsControl source)
{
var list = new List<CheckBox>();
foreach (object dataitem in items)
{
UIElement treeviewitem = source.ItemContainerGenerator.ContainerFromItem(dataitem)
UIElement element = GetChildControl(treeviewitem, "chk");
if (element != null)
{
var chk = (CheckBox)element;
if (chk.IsChecked.HasValue && chk.IsChecked.Value)
{
list.Add(chk);
}
}
List<CheckBox> l = GetSelectedCheckBoxes(item.Items, treeviewitem);
list = list.Concat(l).ToList();
}
return list;
}
但我想强调的是,这不是一种好的做事方式。我敢打赌,你想要实现的目标可以通过一种更为简单,直接和可维护的方式实现,所以我建议你先解释一下它是什么。