【发布时间】:2016-10-09 23:45:21
【问题描述】:
我有这个 TreeView 控件:
<TreeView x:Name="treeView" HorizontalAlignment="Left" Margin="0" Width="300" ItemsSource="{Binding TvMview.FirstNodes}"
VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SecondNodes}">
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ThirdNodes}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding HeaderText}" Background="Red"/>
</StackPanel>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text=">>> " Background="Green"/>
<TextBlock Text="{Binding HeaderText}" Background="blue"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
绑定到:
public class ModelView
{
public TreeViewModelView TvMview { get; set; } = new TreeViewModelView();
}
public class TreeViewModelView
{
public ObservableCollection<FirstNode> FirstNodes { get; set; } = new ObservableCollection<FirstNode>();
}
public class FirstNode : TreeItem
{
public ObservableCollection<SecondNode> SecondNodes { get; set; } = new ObservableCollection<SecondNode>();
public string HeaderText { get; set; }
}
public class SecondNode : TreeItem
{
public ObservableCollection<ThirdNode> ThirdNodes { get; set; } = new ObservableCollection<ThirdNode>();
public string HeaderText { get; set; }
}
public class ThirdNode
{
public string HeaderText { get; set; }
}
public class TreeItem
{
public bool IsExpanded { get; set; }
public bool IsSelected { get; set; }
}
一切都按预期进行。但是...我想实现搜索:
foreach (var firstNode in Mview.TvMview.FirstNodes)
{
if (firstNode.HeaderText.Contains(textBox.Text))
{
firstNode.IsExpanded = true;
firstNode.IsSelected = true;
TreeViewItem tvItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(firstNode);
tvItem?.Focus();
return;
}
}
右节点已展开,但 tvItem 始终为空。我有时在某处读到 ContainerFromItem 不喜欢虚拟化...
有什么想法吗?
谢谢!
【问题讨论】:
-
ContainerFromItem 在项目创建之前将不起作用。尝试将 VirtualizingPanel.IsVirtualizing="False" 添加到您的树视图中。你的视图模型对吗?你实现了 INotifyPropertyChanged 了吗?
-
INotifyPropertyChanged 在 TreeItem 基类中实现。当然……删除虚拟化可以解决问题,但这就是重点……例如,在没有虚拟化的情况下向 TreeView 添加 30.000 个项目:180 秒。使用虚拟化:1 秒。
标签: c# wpf xaml data-binding treeview