How to: Find a TreeViewItem in a TreeView
ItemContainerGenerator Class:与控件关联的 System.Windows.Controls.ItemContainerGenerator。 默认值为 null。
Generates the user interface (UI) on behalf of its host, such as an ItemsControl.
ContainerFromElement(DependencyObject):
返回属于拥有给定元素的当前 System.Windows.Controls.ItemsControl 的容器。
Returns the container that belongs to the current ItemsControl that owns the given element。
Container 相当于控件的项 即ItemControl Item 相当于绑定的数据,
/// <summary> /// Recursively search for an item in this subtree. /// </summary> /// <param name="container"> /// The parent ItemsControl. This can be a TreeView or a TreeViewItem. /// </param> /// <param name="item"> /// The item to search for. /// </param> /// <returns> /// The TreeViewItem that contains the specified item. /// </returns> private TreeViewItem GetTreeViewItem(ItemsControl container, object item) { if (container != null) { if (container.DataContext == item) { return container as TreeViewItem; } // Expand the current container if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded) { container.SetValue(TreeViewItem.IsExpandedProperty, true); } // Try to generate the ItemsPresenter and the ItemsPanel. // by calling ApplyTemplate. Note that in the // virtualizing case even if the item is marked // expanded we still need to do this step in order to // regenerate the visuals because they may have been virtualized away. container.ApplyTemplate(); ItemsPresenter itemsPresenter = (ItemsPresenter)container.Template.FindName("ItemsHost", container); if (itemsPresenter != null) { itemsPresenter.ApplyTemplate(); } else { // The Tree template has not named the ItemsPresenter, // so walk the descendents and find the child. itemsPresenter = FindVisualChild<ItemsPresenter>(container); if (itemsPresenter == null) { container.UpdateLayout(); itemsPresenter = FindVisualChild<ItemsPresenter>(container); } } Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0); // Ensure that the generator for this panel has been created. UIElementCollection children = itemsHostPanel.Children; MyVirtualizingStackPanel virtualizingPanel = itemsHostPanel as MyVirtualizingStackPanel; for (int i = 0, count = container.Items.Count; i < count; i++) { TreeViewItem subContainer; if (virtualizingPanel != null) { // Bring the item into view so // that the container will be generated. virtualizingPanel.BringIntoView(i); subContainer = (TreeViewItem)container.ItemContainerGenerator. ContainerFromIndex(i); } else { subContainer = (TreeViewItem)container.ItemContainerGenerator. ContainerFromIndex(i); // Bring the item into view to maintain the // same behavior as with a virtualizing panel. subContainer.BringIntoView(); } if (subContainer != null) { // Search the next level for the object. TreeViewItem resultContainer = GetTreeViewItem(subContainer, item); if (resultContainer != null) { return resultContainer; } else { // The object is not under this TreeViewItem // so collapse it. subContainer.IsExpanded = false; } } } } return null; } /// <summary> /// Search for an element of a certain type in the visual tree. /// </summary> /// <typeparam name="T">The type of element to find.</typeparam> /// <param name="visual">The parent element.</param> /// <returns></returns> private T FindVisualChild<T>(Visual visual) where T : Visual { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++) { Visual child = (Visual)VisualTreeHelper.GetChild(visual, i); if (child != null) { T correctlyTyped = child as T; if (correctlyTyped != null) { return correctlyTyped; } T descendent = FindVisualChild<T>(child); if (descendent != null) { return descendent; } } } return null; }
The previous code relies on a custom VirtualizingStackPanel that exposes a method named VirtualizingStackPan。
public class MyVirtualizingStackPanel : VirtualizingStackPanel
{
/// <summary>
/// Publically expose BringIndexIntoView.
/// </summary>
public void BringIntoView(int index)
{
this.BringIndexIntoView(index);
}
}
The following XAML shows how to create a TreeView that uses the custom VirtualizingStackPanel.
<TreeView VirtualizingStackPanel.IsVirtualizing="True"> <!--Use the custom class MyVirtualizingStackPanel as the ItemsPanel for the TreeView and TreeViewItem object.--> <TreeView.ItemsPanel> <ItemsPanelTemplate> <src:MyVirtualizingStackPanel/> </ItemsPanelTemplate> </TreeView.ItemsPanel> <TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <src:MyVirtualizingStackPanel/> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView>

浙公网安备 33010602011771号