WPF TreeView tools

在WPF的TreeView使用方式和WinForm下有很大不同,那些展开某节点、获取父节点,判断某节点是否被选中等常用的操作在WinForm下都有相关函数,而在WPF中却不能轻易实现。

一种常规的方式是通过MVVM模式来将TreeViewItem节点中的IsSelect,IsExpanded等属性来双向绑定到要显示的节点数据中,然后直接通过节点数据的属性来实现相关操作。

但是,有的时候,当我们没有ViewModel层,但又想像WinFrom那样直接简单的获取或设置这些属性的时候,该如何办呢。其实WPF还是提供了类似WinForm中的这些设置的,只不过形式不一样了而已,但是却没WinFrom的那么直观和方便。CodeProject上就有人将常用函数总结了一下,写成了扩展函数,主要提供如下功能:

public static void SelectObject(this TreeView treeView, object obj)
public static void SelectObject(this TreeView treeView, object obj, bool selected)
public static bool IsObjectSelected(this TreeView treeView, object obj)
public static bool IsObjectFocused(this TreeView treeView, object obj)
public static void ExpandObject(this TreeView treeView, object obj)
public static void ExpandObject(this TreeView treeView, object obj, bool expanded)
public static bool IsObjectExpanded(this TreeView treeView, object obj)
public static TreeViewItem GetParentItem(this TreeViewItem item)

文章地址如下:WPF TreeView tools

但是,这里面有一个小bug:当TreeView节点中使用延迟绑定的时候,根据数据节点获取TreeItem会失败。这里我把它修正了一下,感兴趣的朋友可以直接使用我修改后的函数。  

代码 


Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->    public static class TreeViewTools
    {
        /// <summary>
        /// Returns the TreeViewItem of a data bound object.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <returns>The TreeViewItem of the data bound object or null.</returns>
        public static TreeViewItem GetItemFromObject(this TreeView treeView, object obj)
        {
            try
            {
                DependencyObject dObject = GetContainerFormObject(treeView, obj);
                TreeViewItem tvi = dObject as TreeViewItem;
                while (tvi == null)
                {
                    dObject = VisualTreeHelper.GetParent(dObject);
                    tvi = dObject as TreeViewItem;
                }
                return tvi;
            }
            catch { }
            return null;
        }

        private static DependencyObject GetContainerFormObject(ItemsControl item, object obj)
        {
            if (item == null)
                return null;

            DependencyObject dObject = null;
            dObject = item.ItemContainerGenerator.ContainerFromItem(obj);

            if (dObject != null)
                return dObject;

            var query = from childItem in item.Items.Cast<object>()
                        let childControl = item.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl
                        select GetContainerFormObject(childControl, obj);

            return query.FirstOrDefault(i => i != null);
        }

        /// <summary>
        /// Selects a data bound object of a TreeView.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        public static void SelectObject(this TreeView treeView, object obj)
        {
            treeView.SelectObject(obj, true);
        }

        /// <summary>
        /// Selects or deselects a data bound object of a TreeView.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <param name="selected">select or deselect</param>
        public static void SelectObject(this TreeView treeView, object obj, bool selected)
        {
            var tvi = treeView.GetItemFromObject(obj);
            if (tvi != null)
            {
                tvi.IsSelected = selected;
            }
        }

        /// <summary>
        /// Returns if a data bound object of a TreeView is selected.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <returns>Returns true if the object is selected, and false if it is not selected or obj is not in the tree.</returns>
        public static bool IsObjectSelected(this TreeView treeView, object obj)
        {
            var tvi = treeView.GetItemFromObject(obj);
            if (tvi != null)
            {
                return tvi.IsSelected;
            }
            return false;
        }

        /// <summary>
        /// Returns if a data bound object of a TreeView is focused.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <returns>Returns true if the object is focused, and false if it is not focused or obj is not in the tree.</returns>
        public static bool IsObjectFocused(this TreeView treeView, object obj)
        {
            var tvi = treeView.GetItemFromObject(obj);
            if (tvi != null)
            {
                return tvi.IsFocused;
            }
            return false;
        }

        /// <summary>
        /// Expands a data bound object of a TreeView.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        public static void ExpandObject(this TreeView treeView, object obj)
        {
            treeView.ExpandObject(obj, true);
        }

        /// <summary>
        /// Expands or collapses a data bound object of a TreeView.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <param name="expanded">expand or collapse</param>
        public static void ExpandObject(this TreeView treeView, object obj, bool expanded)
        {
            var tvi = treeView.GetItemFromObject(obj);
            if (tvi != null)
            {
                tvi.IsExpanded = expanded;
                if (expanded)
                {
                    // update layout, so that following calls to f.e. SelectObject on child nodes will 
                    // find theire TreeViewNodes
                    treeView.UpdateLayout();
                }
            }
        }

        /// <summary>
        /// Returns if a douta bound object of a TreeView is expanded.
        /// </summary>
        /// <param name="treeView">TreeView</param>
        /// <param name="obj">Data bound object</param>
        /// <returns>Returns true if the object is expanded, and false if it is collapsed or obj is not in the tree.</returns>
        public static bool IsObjectExpanded(this TreeView treeView, object obj)
        {
            var tvi = treeView.GetItemFromObject(obj);
            if (tvi != null)
            {
                return tvi.IsExpanded;
            }
            return false;
        }

        /// <summary>
        /// Retuns the parent TreeViewItem.
        /// </summary>
        /// <param name="item">TreeViewItem</param>
        /// <returns>Parent TreeViewItem</returns>
        public static TreeViewItem GetParentItem(this TreeViewItem item)
        {
            var dObject = VisualTreeHelper.GetParent(item);
            TreeViewItem tvi = dObject as TreeViewItem;
            while (tvi == null)
            {
                dObject = VisualTreeHelper.GetParent(dObject);
                tvi = dObject as TreeViewItem;
            }
            return tvi;
        }
    }


 

WPF TreeView是一种在WPF(Windows Presentation Foundation)应用程序中使用的控件,用于以分层结构显示数据。它类似于树形结构,其中每个节点可以有零个或多个子节点。 TreeView由一系列TreeNode组成,每个TreeNode代表一个节点。每个TreeNode可以包含一个或多个子节点,并且可以通过展开和折叠来显示或隐藏这些子节点。每个节点可以具有自定义的显示内容,通常是文本,也可以是任何WPF元素。 使用WPF TreeView,您可以创建具有层次结构的导航菜单、文件资源管理器、组织架构图等应用程序。您可以自定义节点的外观和行为,以及处理节点的选择和展开事件。 要使用WPF TreeView,您需要在XAML中声明TreeView和TreeNode。然后,您可以通过添加和删除TreeNode来动态构建树状结构,并使用数据绑定来显示和编辑树上的数据。 以下是一个简单的示例,演示如何在XAML中创建一个简单的TreeView: ```xaml <TreeView> <TreeViewItem Header="Root"> <TreeViewItem Header="Child 1" /> <TreeViewItem Header="Child 2" /> <TreeViewItem Header="Child 3"> <TreeViewItem Header="Grandchild 1" /> <TreeViewItem Header="Grandchild 2" /> </TreeViewItem> </TreeViewItem> </TreeView> ``` 这将创建一个具有三个一级节点的简单树状结构。您可以通过展开和折叠节点来显示或隐藏子节点。 希望这可以帮助您了解WPF TreeView的基本概念和用法。如果您有更具体的问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值