WPF中TreeView.BringIntoView方法的替代方案
???????????????????????????? WPF中TreeView.BringIntoView方法的替代方案
?????????????????????????????????????? 周銀輝
WPF中TreeView.BringIntoView()方法并不是那么地好用,不少時候會沒有效果,這里有一個替代方案,調用SelectItem()方法可以展開并呈現TreeView上指定的Item:
? public static class TreeViewHelper
??? {
??????? /// <summary>
??????? /// Expands all children of a TreeView
??????? /// </summary>
??????? /// <param name="treeView">The TreeView whose children will be expanded</param>
??????? public static void ExpandAll(this TreeView treeView)
??????? {
??????????? ExpandSubContainers(treeView);
??????? }
?
??????? /// <summary>
??????? /// Expands all children of a TreeView or TreeViewItem
??????? /// </summary>
??????? /// <param name="parentContainer">The TreeView or TreeViewItem containing the children to expand</param>
??????? private static void ExpandSubContainers(ItemsControl parentContainer)
??????? {
??????????? foreach (Object item in parentContainer.Items)
??????????? {
??????????????? TreeViewItem currentContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
??????????????? if (currentContainer != null && currentContainer.Items.Count > 0)
??????????????? {
??????????????????? //expand the item
??????????????????? currentContainer.IsExpanded = true;
?
??????????????????? //if the item's children are not generated, they must be expanded
??????????????????? if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
??????????????????? {
??????????????????????? //store the event handler in a variable so we can remove it (in the handler itself)
??????????????????????? EventHandler eh = null;
??????????????????????? eh = new EventHandler(delegate
??????????????????????????? {
?????????????? ?????????????????//once the children have been generated, expand those children's children then remove the event handler
??????????????????????????????? if (currentContainer.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
??????????? ????????????????????{
??????????????????????????????????? ExpandSubContainers(currentContainer);
??????????????????????????????????? currentContainer.ItemContainerGenerator.StatusChanged -= eh;
??????????????????????????????? }
??????????????????????????? });
?
??????????????????????? currentContainer.ItemContainerGenerator.StatusChanged += eh;
??????????????????? }
??????????????????? else //otherwise the children have already been generated, so we can now expand those children
??????????????????? {
?????? ?????????????????ExpandSubContainers(currentContainer);
??????????????????? }
??????????????? }
??????????? }
??????? }
?
??????? /// <summary>
??????? /// Searches a TreeView for the provided object and selects it if found
??????? /// </summary>
??????? /// <param name="treeView">The TreeView containing the item</param>
??????? /// <param name="item">The item to search and select</param>
??????? public static void SelectItem(this TreeView treeView, object item)
??????? {
??????????? ExpandAndSelectItem(treeView, item);
??????? }
?
??????? /// <summary>
??????? /// Finds the provided object in an ItemsControl's children and selects it
??????? /// </summary>
??????? /// <param name="parentContainer">The parent container whose children will be searched for the selected item</param>
??????? /// <param name="itemToSelect">The item to select</param>
??????? /// <returns>True if the item is found and selected, false otherwise</returns>
??????? private static bool ExpandAndSelectItem(ItemsControl parentContainer, object itemToSelect)
??????? {
??????????? //check all items at the current level
??????????? foreach (Object item in parentContainer.Items)
??????????? {
??????????????? TreeViewItem currentContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
?
??????????????? //if the data item matches the item we want to select, set the corresponding
??????????????? //TreeViewItem IsSelected to true
??????????????? if (item == itemToSelect && currentContainer != null)
??????????????? {
??????????????????? currentContainer.IsSelected = true;
??????????????????? currentContainer.BringIntoView();
??????????????????? currentContainer.Focus();
?
??????????????????? //the item was found
??????????????????? return true;
??????????????? }
??????????? }
?
??????????? //if we get to this point, the selected item was not found at the current level, so we must check the children
??????????? foreach (Object item in parentContainer.Items)
??????????? {
??????????????? TreeViewItem currentContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
?
??????????????? //if children exist
??????????????? if (currentContainer != null && currentContainer.Items.Count > 0)
???????? ???????{
??????????????????? //keep track of if the TreeViewItem was expanded or not
??????????????????? bool wasExpanded = currentContainer.IsExpanded;
?
??????????????????? //expand the current TreeViewItem so we can check its child TreeViewItems
??????? ????????????currentContainer.IsExpanded = true;
?
??????????????????? //if the TreeViewItem child containers have not been generated, we must listen to
??????????????????? //the StatusChanged event until they are
??????????????????? if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
??????????????????? {
??????????????????????? //store the event handler in a variable so we can remove it (in the handler itself)
??????????????????????? EventHandler eh = null;
?????????? ?????????????eh = new EventHandler(delegate
??????????????????????? {
??????????????????????????? if (currentContainer.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
??????????????????????????? {
??????????????????????????????? if (ExpandAndSelectItem(currentContainer, itemToSelect) == false)
??????????????????????????????? {
??????????????????????????????????? //The assumption is that code executing in this EventHandler is the result of the parent not
??????????????????????????????? ????//being expanded since the containers were not generated.
??????????????????????????????????? //since the itemToSelect was not found in the children, collapse the parent since it was previously collapsed
??????????????????????????????????? currentContainer.IsExpanded = false;
??????????????????????????????? }
?
??????????????????????????????? //remove the StatusChanged event handler since we just handled it (we only needed it once)
???????????????????????? ???????currentContainer.ItemContainerGenerator.StatusChanged -= eh;
??????????????????????????? }
??????????????????????? });
??????????????????????? currentContainer.ItemContainerGenerator.StatusChanged += eh;
??????????????????? }
??????????????????? else //otherwise the containers have been generated, so look for item to select in the children
??????????????????? {
??????????????????????? if (ExpandAndSelectItem(currentContainer, itemToSelect) == false)
??????????????????????? {
???????????????????????? ???//restore the current TreeViewItem's expanded state
??????????????????????????? currentContainer.IsExpanded = wasExpanded;
??????????????????????? }
??????????????????????? else //otherwise the node was found and selected, so return true
?????????????? ?????????{
??????????????????????????? return true;
??????????????????????? }
??????????????????? }
??????????????? }
??????????? }
?
??????????? //no item was found
??????????? return false;
??????? }
??? }
?
轉載于:https://www.cnblogs.com/zhouyinhui/archive/2008/12/22/1360033.html
總結
以上是生活随笔為你收集整理的WPF中TreeView.BringIntoView方法的替代方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC创建字体
- 下一篇: 《你必须知道的.NET》第1章学习笔记