DevExpress TreeList实现TreeView普通样式

DevExpress TreeList实现TreeView普通样式

背景

由于最近项目中,客户指定界面组件要使用DevExpress第三方控件,因此就熟悉了DevExpress中常用控件的一些用法,现把一些重要控件的常见用法进行总结分享。

TreeList

在DevExpress中TreeList控件也是一个 很常用的控件,我的其中一个应用场景就是只读显示文件目录结构,因为Dev中的TreeList默认是显示列头和行线的,因此要通过设置只显示1列,并隐藏网格线,隐藏列头的方式实现普通TreeView的样式。先看一些最终的实现效果如下图:
在这里插入图片描述

实现的关键代码如下

1、DataTreeNodeTypes

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wongoing.Gui.DataAnalysis.Common
{
    public enum DataTreeNodeTypes
    {
        /// <summary>
        /// 文件夹
        /// </summary>
        Folder = 0,
        /// <summary>
        /// 文件
        /// </summary>
        File = 1
    }
}

2、DataTreeNode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wongoing.Gui.DataAnalysis.Common
{
    [Serializable]
    public class DataTreeNode
    {
        private string id;
        private string parentId;
        private string nodeText;
        private string createDate;
        private string fullPath;
        private string taskFile;
        private string barcode;
        private DataTreeNodeTypes nodeType = DataTreeNodeTypes.Folder;

        public string Id
        {
            get { return id; }
            set { id = value; }
        }

        public string ParentId
        {
            get { return parentId; }
            set { parentId = value; }
        }

        public string NodeText
        {
            get { return nodeText; }
            set { nodeText = value; }
        }

        public string CreateDate
        {
            get { return createDate; }
            set { createDate = value; }
        }

        public string FullPath
        {
            get { return fullPath; }
            set { fullPath = value; }
        }

        public string TaskFile
        {
            get { return taskFile; }
            set { taskFile = value; }
        }

        public string Barcode
        {
            get { return barcode; }
            set { barcode = value; }
        }

        public DataTreeNodeTypes NodeType
        {
            get { return nodeType; }
            set { nodeType = value; }
        }
    }
}

3、DataTreeListHelper(关键代码)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.Core;

namespace Wongoing.Gui.DataAnalysis.Common
{
    public class DataTreeListHelper
    {
        #region 事件定义

        /// <summary>
        /// 刷新数据事件
        /// </summary>
        public static event EventHandler OnRefreshData;
        /// <summary>
        /// 重新加载选中的数据时间
        /// </summary>
        public static event EventHandler OnReloadSelectData;

        #endregion

        #region 图标数组

        public static System.Drawing.Image[] imgs = new System.Drawing.Image[] { 
            ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_FolderOpen") as System.Drawing.Image,
            ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_FolderClose") as System.Drawing.Image,
            ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_DataNode") as System.Drawing.Image,
            ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_DataNodeSelect") as System.Drawing.Image
        };

        #endregion

        #region 刷新树控件的数据

        /// <summary>
        /// 刷新树控件的数据
        /// </summary>
        /// <param name="treeList">树控件</param>
        /// <param name="expandToLevel">刷新数据后默认展开的级别</param>
        public static void RefreshTreeData(DevExpress.XtraTreeList.TreeList treeList, int expandToLevel)
        {
            string rootNodeId = Common.Global.AppConfig.TestDataDir;
            string rootNodeText =  ICSharpCode.Core.StringParser.Parse(ResourceService.GetString("Pad_DataTree_RootNodeText"));   //"全部实验数据";
            string fieldName = "NodeText";
            string keyFieldName = "Id";
            string parentFieldName = "ParentId";
            List<DataTreeNode> data = new List<DataTreeNode>();
            data = DataTreeListHelper.ParseDir(Common.Global.AppConfig.TestDataDir, data);
            data.Add(new DataTreeNode() { Id = rootNodeId, ParentId = String.Empty, NodeText = rootNodeText, NodeType = DataTreeNodeTypes.Folder });
            DataTreeListHelper.SetTreeListDataSource(treeList, data, fieldName, keyFieldName, parentFieldName);
            treeList.ExpandToLevel(expandToLevel);
        }

        #endregion

        #region 为树控件设置数据源

        /// <summary>
        /// 为树控件设置数据源
        /// </summary>
        /// <param name="treeList">树控件</param>
        /// <param name="data">数据对象</param>
        /// <param name="fieldName">显示的字段</param>
        /// <param name="keyFieldName">键字段</param>
        /// <param name="parentFieldName">父级键字段</param>
        public static void SetTreeListDataSource(DevExpress.XtraTreeList.TreeList treeList, List<DataTreeNode> data, string fieldName, string keyFieldName, string parentFieldName)
        {
            #region 设置节点图标

            System.Windows.Forms.ImageList imgList = new System.Windows.Forms.ImageList();
            imgList.Images.AddRange(imgs);

            treeList.SelectImageList = imgList;

            //目录展开
            treeList.AfterExpand -= treeList_AfterExpand;
            treeList.AfterExpand += treeList_AfterExpand;

            //目录折叠
            treeList.AfterCollapse -= treeList_AfterCollapse;
            treeList.AfterCollapse += treeList_AfterCollapse;

            //数据节点单击,开启整行选中
            treeList.MouseClick -= treeList_MouseClick;
            treeList.MouseClick += treeList_MouseClick;

            //数据节点双击选中
            treeList.MouseDoubleClick -= treeList_MouseDoubleClick;
            treeList.MouseDoubleClick += treeList_MouseDoubleClick;

            //焦点离开事件
            treeList.LostFocus -= treeList_LostFocus;
            treeList.LostFocus += treeList_LostFocus;


            #endregion

            #region 设置列头、节点指示器面板、表格线样式

            treeList.OptionsView.ShowColumns = false;             //隐藏列标头
            treeList.OptionsView.ShowIndicator = false;           //隐藏节点指示器面板

            treeList.OptionsView.ShowHorzLines = false;           //隐藏水平表格线
            treeList.OptionsView.ShowVertLines = false;           //隐藏垂直表格线
            treeList.OptionsView.ShowIndentAsRowStyle = false;

            #endregion

            #region 初始禁用单元格选中,禁用整行选中

            treeList.OptionsView.ShowFocusedFrame = true;                               //设置显示焦点框
            treeList.OptionsSelection.EnableAppearanceFocusedCell = false;              //禁用单元格选中
            treeList.OptionsSelection.EnableAppearanceFocusedRow = false;               //禁用正行选中
            //treeList.Appearance.FocusedRow.BackColor = System.Drawing.Color.Red;      //设置焦点行背景色

            #endregion

            #region 设置TreeList的展开折叠按钮样式和树线样式

            treeList.OptionsView.ShowButtons = true;                  //显示展开折叠按钮
            treeList.LookAndFeel.UseDefaultLookAndFeel = false;       //禁用默认外观与感觉
            treeList.LookAndFeel.UseWindowsXPTheme = true;            //使用WindowsXP主题
            treeList.TreeLineStyle = DevExpress.XtraTreeList.LineStyle.Percent50;     //设置树线的样式 

            #endregion

            #region 添加单列

            DevExpress.XtraTreeList.Columns.TreeListColumn colNode = new DevExpress.XtraTreeList.Columns.TreeListColumn();
            colNode.Name = String.Format("col{0}", fieldName);
            colNode.Caption = fieldName;
            colNode.FieldName = fieldName;
            colNode.VisibleIndex = 0;
            colNode.Visible = true;

            colNode.OptionsColumn.AllowEdit = false;                        //是否允许编辑
            colNode.OptionsColumn.AllowMove = false;                        //是否允许移动
            colNode.OptionsColumn.AllowMoveToCustomizationForm = false;     //是否允许移动至自定义窗体
            colNode.OptionsColumn.AllowSort = false;                        //是否允许排序
            colNode.OptionsColumn.FixedWidth = false;                       //是否固定列宽
            colNode.OptionsColumn.ReadOnly = true;                          //是否只读
            colNode.OptionsColumn.ShowInCustomizationForm = true;           //移除列后是否允许在自定义窗体中显示

            treeList.Columns.Clear();
            treeList.Columns.AddRange(new DevExpress.XtraTreeList.Columns.TreeListColumn[] { colNode });

            #endregion

            #region 绑定数据源

            treeList.KeyFieldName = keyFieldName;
            treeList.ParentFieldName = parentFieldName;
            treeList.DataSource = data;
            treeList.RefreshDataSource();

            #endregion

            #region 初始化图标

            SetNodeImageIndex(treeList.Nodes.FirstOrDefault());

            #endregion
        }

        /// <summary>
        /// 焦点离开时,当前节点背景色整行选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void treeList_LostFocus(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(Global.Instance.CurrDataFile))
            {
                DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
                if (treeList != null && treeList.Selection.Count == 1)
                {
                    DevExpress.XtraTreeList.Nodes.TreeListNode node = treeList.FindNodeByKeyID(Global.Instance.CurrDataFile);
                    if (node != null)
                    {
                        if (!node.Selected)
                        {
                            treeList.OptionsSelection.EnableAppearanceFocusedRow = true;                                //启用整行选中
                            node.Selected = true;
                            Common.DataTreeListHelper.SetNodeImageIndex(treeList.Nodes.FirstOrDefault());
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 节点展开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void treeList_AfterExpand(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
        {
            e.Node.ImageIndex = 0;
            e.Node.SelectImageIndex = e.Node.ImageIndex;
        }

        /// <summary>
        /// 节点折叠
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void treeList_AfterCollapse(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
        {
            e.Node.ImageIndex = 1;
            e.Node.SelectImageIndex = e.Node.ImageIndex;
        }

        /// <summary>
        /// 单击数据节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void treeList_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
            if (treeList != null && treeList.Selection.Count == 1)
            {
                object idValue = null;
                string strIdValue = String.Empty;
                DataTreeNode nodeData = null;
                List<DataTreeNode> datasource = treeList.DataSource as List<DataTreeNode>;
                if (datasource != null)
                {
                    idValue = treeList.Selection[0].GetValue("Id");
                    strIdValue = idValue.ToString();
                    nodeData = datasource.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
                    if (nodeData != null)
                    {
                        if (nodeData.NodeType == DataTreeNodeTypes.File)
                        {
                            treeList.OptionsSelection.EnableAppearanceFocusedRow = true;                                //启用整行选中
                            return;
                        }
                    }
                }
                treeList.OptionsSelection.EnableAppearanceFocusedRow = false;                                //禁用整行选中
            }
        }

        /// <summary>
        /// 双击数据节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void treeList_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
            if (treeList != null && treeList.Selection.Count == 1)
            {
                object idValue = null;
                string strIdValue = String.Empty;
                DataTreeNode nodeData = null;
                List<DataTreeNode> datasource = treeList.DataSource as List<DataTreeNode>;
                if (datasource != null)
                {
                    idValue = treeList.Selection[0].GetValue("Id");
                    strIdValue = idValue.ToString();
                    nodeData = datasource.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
                    if (nodeData != null)
                    {
                        if (nodeData.NodeType == DataTreeNodeTypes.File)
                        {
                            SetNodeImageIndex(treeList.Nodes.FirstOrDefault());
                            Wongoing.PlugIn.Event.ParamEventArgs pea = new PlugIn.Event.ParamEventArgs(nodeData.Id);
                            TriggerReloadSelectDataEvent(sender, pea);
                            return;
                        }
                    }
                }
            }
        }

        #endregion

        #region 递归设置节点图标

        /// <summary>
        /// 递归设置节点图标
        /// </summary>
        /// <param name="node">要设置图标的节点</param>
        public static void SetNodeImageIndex(DevExpress.XtraTreeList.Nodes.TreeListNode node)
        {
            object idValue = null;
            string strIdValue = String.Empty;
            DataTreeNode nodeData = null;

            List<DataTreeNode> data = node.TreeList.DataSource as List<DataTreeNode>;
            if (data != null)
            {
                idValue = node.GetValue("Id");
                strIdValue = idValue.ToString();
                nodeData = data.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
                if (nodeData != null)
                {
                    if (nodeData.NodeType == DataTreeNodeTypes.Folder)
                    {
                        //文件夹
                        if (node.Expanded)
                        {
                            //展开
                            node.ImageIndex = 0;
                            node.SelectImageIndex = 0;
                        }
                        else
                        {
                            //折叠
                            node.ImageIndex = 1;
                            node.SelectImageIndex = 1;
                        }
                    }
                    else
                    {
                        //文件
                        if (!node.Selected)
                        {
                            //默认
                            node.ImageIndex = 2;
                            node.SelectImageIndex = 2;
                        }
                        else
                        {
                            //选中
                            node.ImageIndex = 3;
                            node.SelectImageIndex = 3;
                        }
                    }
                }

                foreach(DevExpress.XtraTreeList.Nodes.TreeListNode childNode in node.Nodes)
                {
                    SetNodeImageIndex(childNode);
                }
            }
        }

        #endregion

        #region 解析实验数据目录

        /// <summary>
        /// 解析实验数据目录
        /// </summary>
        /// <param name="dataRootDir">实验数据根目录</param>
        /// <returns>返回数据节点列表对象</returns>
        public static List<DataTreeNode> ParseDir(string dataRootDir, List<DataTreeNode> data)
        {
            if (data == null)
            {
                data = new List<DataTreeNode>();
            }

            if (!System.IO.Directory.Exists(dataRootDir))
            {
                return data;
            }

            DataTreeNode node = null;

            System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(dataRootDir);

            System.IO.DirectoryInfo[] subDirs = dir.GetDirectories();
            foreach(System.IO.DirectoryInfo subDir in subDirs)
            {
                node = new DataTreeNode();
                node.Id = subDir.FullName;
                node.ParentId = dir.FullName;
                node.NodeText = subDir.Name;
                node.CreateDate = String.Format("{0:yyyy-MM-dd HH:mm:ss}", subDir.CreationTime);
                node.FullPath = subDir.FullName;
                node.TaskFile = String.Empty;           //任务文件名
                node.NodeType = DataTreeNodeTypes.Folder;
                data.Add(node);

                ParseDir(subDir.FullName, data);
            }

            System.IO.FileInfo[] subFiles = dir.GetFiles();
            foreach(System.IO.FileInfo subFile in subFiles)
            {
                //如果包含索引数据文件
                if (subFile.Name.Contains(Global.INDEX_EXT))
                {
                    node = new DataTreeNode();
                    node.Id = subFile.FullName.Replace(Global.INDEX_EXT, String.Empty);
                    node.ParentId = dir.FullName;
                    node.NodeText = subFile.Name.Replace(Global.INDEX_EXT, String.Empty);
                    node.CreateDate = String.Format("{0:yyyy-MM-dd HH:mm:ss}", subFile.CreationTime);
                    node.FullPath = subFile.FullName;
                    node.TaskFile = String.Empty;               //任务文件名
                    node.NodeType = DataTreeNodeTypes.File;
                    data.Add(node);
                }
            }

            return data;
        }

        #endregion

        #region 触发事件

        #region 触发刷新数据事件

        /// <summary>
        /// 触发刷新数据事件
        /// </summary>
        public static void TriggerRefreshDataEvent()
        {
            if (OnRefreshData != null)
            {
                OnRefreshData(null, System.EventArgs.Empty);
            }
        }

        #endregion

        #region 触发重新加载选中数据事件

        public static void TriggerReloadSelectDataEvent(object sender, System.EventArgs e)
        {
            if (OnReloadSelectData != null)
            {
                OnReloadSelectData(sender, e);
            }
        }

        #endregion

        #endregion
    }
}

4、窗体界面的调用代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Wongoing.Gui.DataAnalysis.Pad
{
    using Wongoing.Gui.Dev.Pad;
    public partial class DataTreePad : DefaultPadContent
    {
        private int defaultExpandLevel = 2;

        public DataTreePad()
        {
            InitializeComponent();
        }

        private void DataTreePad_Load(object sender, EventArgs e)
        {
            Wongoing.Basic.LanguageHelper.LanguageChanged -= LanguageHelper_LanguageChanged;
            Wongoing.Basic.LanguageHelper.LanguageChanged += LanguageHelper_LanguageChanged;
            Common.DataTreeListHelper.OnRefreshData -= DataTreeListHelper_OnRefreshData;
            Common.DataTreeListHelper.OnRefreshData += DataTreeListHelper_OnRefreshData;
            Common.DataTreeListHelper.OnReloadSelectData -= DataTreeListHelper_OnReloadSelectData;
            Common.DataTreeListHelper.OnReloadSelectData += DataTreeListHelper_OnReloadSelectData;

            //刷新树控件数据
            Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
        }

        /// <summary>
        /// 切换语言是刷新数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void LanguageHelper_LanguageChanged(object sender, EventArgs e)
        {
            Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
        }

        /// <summary>
        /// 刷新事件触发时刷新数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DataTreeListHelper_OnRefreshData(object sender, EventArgs e)
        {
            Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
            if (!String.IsNullOrEmpty(Common.Global.Instance.CurrDataFile))
            {
                DevExpress.XtraTreeList.Nodes.TreeListNode node = this.treeList1.FindNodeByKeyID(Common.Global.Instance.CurrDataFile);
                if (node != null)
                {
                    if (!node.Selected)
                    {
                        this.treeList1.OptionsSelection.EnableAppearanceFocusedRow = true;                                //启用整行选中
                        node.Selected = true;
                        Common.DataTreeListHelper.SetNodeImageIndex(this.treeList1.Nodes.FirstOrDefault());
                    }
                }
            }
        }

        /// <summary>
        /// 重新加载选择数据后,如果对应的文件节点没有选中,则进行选中,主要是对应查询对话框的选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataTreeListHelper_OnReloadSelectData(object sender, EventArgs e)
        {
            if (e is Wongoing.PlugIn.Event.ParamEventArgs)
            {
                Wongoing.PlugIn.Event.ParamEventArgs pea = e as Wongoing.PlugIn.Event.ParamEventArgs;
                string id = pea.Parameter as string;
                DevExpress.XtraTreeList.Nodes.TreeListNode node = this.treeList1.FindNodeByKeyID(id);
                if (node != null)
                {
                    if (!node.Selected)
                    {
                        node.Selected = true;
                        Common.DataTreeListHelper.SetNodeImageIndex(this.treeList1.Nodes.FirstOrDefault());
                    }
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值