我正在尝试将搜索功能添加到WPF中的TreeView。我成功地为一个只有一个级别的TreeView添加和搜索树项目,但对于具有多个级别的TreeView,我无法弄清楚如何访问一个子控件(UIElement
)树型视图。当我将ItemContainerGenerator.ContainerFromItem()
作为参数传递时,TreeViewItem.Item
返回null。我看到几个帖子讨论了同样的问题,但没有一个解决方案适合我。
这是我的XAML代码。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="72*" />
</Grid.RowDefinitions>
<StackPanel x:Name="SearchTextBox" Grid.Row="0" Margin="5,5,5,0"/>
<TreeView Name="MyTreeView" Grid.Row="1" BorderThickness="0">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Students}">
<TextBlock Margin="3" Text="{Binding SchoolName}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StudentName}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
这是我的C#代码
public class MyClass
{
public string ClassName { get; set; }
public List<Student> Students { get; set; }
}
public class Student
{
public string StudentName { get; set; }
}
private void PlanSearchOnSearchInputChanged(string searchQuery)
{
List<TreeViewItem> items = GetLogicalChildCollection(MyTreeView);
}
public static List<TreeViewItem> GetLogicalChildCollection(TreeView parent)
{
var logicalCollection = new List<TreeViewItem>();
foreach (var child in parent.Items)
{
TreeViewItem item = (TreeViewItem)parent.ItemContainerGenerator.ContainerFromItem(child);
logicalCollection.Add(item);
GetLogicalChildCollection(item, logicalCollection);
}
return logicalCollection;
}
public static List<TreeViewItem> GetLogicalChildCollection(TreeViewItem parent, List<TreeViewItem> logicalCollection)
{
foreach (var child in parent.Items)
{
TreeViewItem item = (TreeViewItem)parent.ItemContainerGenerator.ContainerFromItem(child);
logicalCollection.Add(item);
}
return logicalCollection;
}
PS:我需要访问项目的UIElement,而不仅仅是项目。 任何帮助将不胜感激。
答案 0 :(得分:1)
如果TreeViewItem未展开,那么它的子节点将没有任何UI,因此您无法获取其子节点。也许这就是你所看到的问题。
这是一些要考虑的代码,我没有你的所有代码来轻松地解决正在发生的事情,但这适用于我的样本。它既快又脏,而不是超级优雅。
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var item in tv.Items)
{
TreeViewItem tvi = tv.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
tvi.IsExpanded = true;
tvi.UpdateLayout();
RecurseItem(tvi);
}
}
private bool gotTheItem = false;
private void RecurseItem(TreeViewItem item)
{
foreach (var subItem in item.Items)
{
TreeViewItem tvi = item.ItemContainerGenerator.ContainerFromItem(subItem) as TreeViewItem;
// do something
if (!gotTheItem)
{
RecurseItem(tvi);
}
}
}
您可以在展开项目时可能会设置IsExpanded
或挂钩事件,也可能是其他一些内容。
答案 1 :(得分:0)
电视有一个节点集合。每个节点还有一个节点集合。
您需要从根开始,检查每个节点,以及该节点是否包含长度为&gt;的节点集合。 0,你需要进入它。
这通常使用递归树步行来完成。