程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WPF中TreeView.BringIntoView方法的替代方案

WPF中TreeView.BringIntoView方法的替代方案

編輯:關於.NET

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;
    }
  }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved