zoukankan      html  css  js  c++  java
  • WPF中TreeView.BringIntoView方法的替代方案

     WPF中TreeView.BringIntoView方法的替代方案   (转)

    原文地址:https://www.cnblogs.com/zhouyinhui/archive/2008/12/22/1360033.html     

     周银辉

    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;

            }

        }

  • 相关阅读:
    fixed与sticky的区别
    自我介绍以及web课程目标
    DOM&BOM
    web中常用单位的使用
    Oracle 使用 DBLINK详解(转载) 挪威
    Sql server 无法删除用户的处理办法(转载) 挪威
    ICMP类型
    makefile笔记
    [笔记]Makefile wildcard
    在Visual Studio 2005下配置WinPcap开发环境
  • 原文地址:https://www.cnblogs.com/zwswood/p/12090374.html
Copyright © 2011-2022 走看看