Winform开发主界面菜单的动态树形列表展示

我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一二级菜单,这种方式在一般功能点不算太多的情况下,呈现的界面效果较为直观、也较为美观。不过随着一些系统功能的增多,这种方式可能就会显得工具栏比较拥挤,那么我们是否可以在左侧放置一个树形列表,这样通过树形列表的收缩折叠,就可以放置非常多的菜单功能了。

1、菜单的树形列表展示

一般情况下,树形列表的显示可以分为多个节点,节点可以收缩也可以展开,当然节点是有不同的图标的了。这样就可以把很多功能点整合在一个树列表里面了,树的节点也可以分为很多级别,很多层次

  

如果我们想按照业务的范畴来区分,也可以分为多个模块展示,类似选项卡的方式,一个模块的功能菜单列表集合在一起展示,如下所示。

上面这样的折叠展示,有利于业务范畴的区分,并且可以让树菜单菜单不会很大,是一种比较好的界面组织方式。

2、菜单的动态配置管理

上面介绍了树形菜单的展示,以及如何组织菜单的内容,做好这些,就为我们奠定了界面菜单组织的雏形了。

那么问题来了,我们一般是需要根据系统创建很多菜单的,如果是能通过配置的方式,这样才能较好的管理这些菜单,而且可以动态给菜单指定权限,实现不同角色用户的权限控制。

那么我们就需要在系统里面引入一个菜单管理模块,实现菜单的配置管理功能,方便我们后面的动态创建菜单操作。

通过菜单的配置,我们可以指定菜单的图标,是否可见,是否展开,权限控制点,以及菜单触发点击后,处理的窗体对象等信息,有了这些基础信息,我们就很方便把菜单在树形列表里面进行合适、美观的展示了。

3、菜单动态构建的实现

前面介绍了,如何在数据库里面对菜单数据进行了存储,这样我们就可以在系统主界面里面,动态的构建属性列表进行菜单的展示操作了。

首先,我们需要在设计时刻对主界面的布局进行一定的设计,放置一些初始化的树形列表,方便查看效果。至于里面的内容,我们可以根据数据库的菜单配置,动态从数据库里面获取菜单信息,在左侧树形列表里面进行构建。

我们可以通过一个辅助类进行菜单的动态创建,如下所示。

        private void InitToolbar()
        {
            TreeMenuHelper helper = new TreeMenuHelper(this, this.nvBarMenu, this.imageList1);
            helper.Init();
        }

也就是辅助类,传入当前窗体,以及左侧的导航控件等参数后,我们在辅助类里面封装对应的动态构建菜单的逻辑处理。

首先我们动态创建的开始,先要清空原来控件展示的菜单内容,并重新从数据库里面获取,如下代码所示。

            //清空所有导航控件的内容
            barControl.Controls.Clear();
            barControl.Groups.Clear();
            barControl.Items.Clear();
            this.imageList.Images.Clear();

            //限定显示几个导航选项卡
            barControl.NavigationPaneMaxVisibleGroups = 3;

            //约定菜单共有3级,第一级为大的类别,第二级为小模块分组,第三级为具体的菜单
            List<MenuNodeInfo> menuList = BLLFactory<SysMenu>.Instance.GetTree(Portal.gc.SystemType);
            if (menuList.Count == 0) return;

然后我们会对菜单进行遍历,并判断是否具有对应的权限点,如果没有对应的权限,那么对应菜单的子菜单也不会进一步展示。

            //递归遍历所有的菜单,进行分级展示
            foreach (MenuNodeInfo firstInfo in menuList)
            {
                //如果没有菜单的权限,则跳过
                if (!Portal.gc.HasFunction(firstInfo.FunctionId)) continue;

创建菜单的时候,我们注意到整个菜单项是动态构建的,因此我们需要根据NavBarControl的控件属性,动态构建对应的选项卡NavBarGroup、展示容器NavBarGroup、树形对象TreeView、树形节点TreeNode等内容,如下代码所示。

                TreeView treeView = new TreeView();
                treeView.Dock = DockStyle.Fill;
                treeView.ImageList = this.imageList;
                treeView.ItemHeight = 30;//设置高度,显示更美观

                NavBarGroupControlContainer container = new NavBarGroupControlContainer();
                container.Size = new System.Drawing.Size(213, 412);
                container.Controls.Add(treeView);
                barControl.Controls.Add(container);

                //加载图标
                this.imageList.Images.Add(LoadIcon(firstInfo.Icon));
                int index = this.imageList.Images.Count - 1;//最后一个序号

                NavBarGroup group = new NavBarGroup();
                group.Caption = firstInfo.Name;
                group.ControlContainer = container;
                group.Expanded = true;
                group.GroupClientHeight = 410;
                group.GroupStyle = NavBarGroupStyle.ControlContainer;
                group.LargeImageIndex = index;
                group.SmallImageIndex = index;
                barControl.Groups.Add(group);

                //创建一级列表
                TreeNode pNode = new TreeNode();
                pNode.Text = firstInfo.Name;
                pNode.Tag = firstInfo.WinformType;
                pNode.ImageIndex = index;
                pNode.SelectedImageIndex = index;
                treeView.Nodes.Add(pNode);

                //递归创建子列表
                AddTreeItems(pNode, firstInfo.Children);

通过递归的方式,我们就很容易递归构建了所有层次的树形菜单,并进行合适的展示了。

菜单的单击事件,我们通过一个函数代码实现对它进行处理就可以了。

                //处理树形菜单的点击操作,如果TAG存在,则解析并加载对应的页面到多文档里面
                treeView.AfterSelect += (sender, e) =>
                {
                    string tag = e.Node.Tag as string;
                    if (!string.IsNullOrEmpty(tag))
                    {
                        LoadPlugInForm(tag);
                    }
                };

这里面就是对它的AfterSelect 事件进行处理,实现我们动态加载窗体对象到多文档界面的处理了。

4、系统界面的总体效果

最后,为了更好理解整个动态菜单的界面效果,贴出几个做好的界面展示图,供参考学习。

1)标准界面的处理方式

2)树形列表界面的处理方式

打开多文档页面后如下所示。

时间: 2024-08-06 07:34:21

Winform开发主界面菜单的动态树形列表展示的相关文章

Winform开发框架主界面设计展示

做了好多年Winform的程序的开发,主窗口的界面设计一般都要求做的更好一些,可以根据不同的系统功能模块进行归类整合,能使客户迅速寻找到相关功能的同时,也能感觉到整体性的美观大方,因此主窗口的界面设计总是会精益求精,力求做到更好用.更美观,这样才能吸引客户使用. 目前的主体界面设计,可以使用很多控件进行美化,这样能使得开发者能够迅速开发好美观的界面,也可以使得界面总体性有一个统一.规范的基准.一般推荐使用DevExpress或者DotNetbar这两款界面控件套件,他们都能设计出类似Office

winform 防止主界面卡死

总结网络上的解决方案:新线程=> 委托=> 主界面的异步更新方法(IAsyncResult BeginInvoke(Delegate method)),一句话就是通过委托调用另一个线程的异步方法. 验证方法:当线程执行时,拖拽主窗体,没有卡死迹象. 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawi

Ajax-ajax实例3-动态树形列表

项目结构: 项目演示: 技术要点: 1.3.2 技术要点在基本原理的介绍中,了解到通过在父节点内动态创建子节点,并利用样式表缩进完成树形列表的基本框架.除了这一点外,还有下面一些问题需要考虑.1 .将父节点所有的子节点放入一个容器中基本原理页面中仅包含了创建子节点的功能,不可以将创建好的节点再进行关闭操作.实际应用中菜单总是包含打开和关闭两种操作.为了方便进行关闭操作,将子节点放入一个容器中,在关闭时只需要设置容器的显示属性即可.2 .节点开关的具体实现每个父节点的所有子节点放入容器中后,在单击

在Winform界面菜单中实现动态增加【最近使用的文件】菜单项

在我们一些和文件处理打交道的系统中,我们往往需要记录下最近使用的文件,这样方便用户快速打开之前浏览或者编辑过的文件,这种在很多软件上很常见,本文主要介绍在Winform界面菜单中实现[最近使用的文件]动态菜单的处理,实现一个较为常用的功能. 在我上篇随笔<文字处理控件TX Text Control的使用>介绍的内容中,我针对性的对这个控件的使用做了一个全面的了解,发现其中案例代码总这部分的功能实现[最近使用的文件]挺好,于是把它进行了整理,把整个思路作为一篇随笔进行记录,希望对大家有所帮助.

会员管理系统的设计和开发(3)--主界面的设计思路分享

会员管理系统经过一段时间的紧锣密鼓开发,软件终于完成并发布.在这期间,碰到了不少技术难点,并积累了不少开发心得和经验,本篇继续介绍这个开发过程中相关的技术要点,本章主要介绍会员管理里面,列表主界面的一些设计思路分享. 有时候,遵循一些固定的套路做事情,总是很容易,如果每个地方搞一些创新和改进,那么往往需要花费很多时间,但是创新是有积极意义的,虽然可能会遇到困难,但是很值得去做.在Winform的界面设计上,虽然我可以使用代码生成工具生成比较标准的界面了,但是我总是喜欢参考学习,并改进一些界面方面

ABP开发框架前后端开发系列---(11)菜单的动态管理

在前面随笔<ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理>中介绍了基于ABP框架服务构建的Winform客户端,客户端通过Web API调用的方式进行获取数据,从而实现了对组织机构.角色.用户.权限等管理,其中没有涉及菜单部分,本篇随笔介绍在ABP框架中实现菜单的管理,菜单是作为Winform或者Web动态构建界面的一个重要元素,同时也是作为角色权限控制的部分资源. 1.菜单的列表展示和管理 一般情况下,菜单的树形列表的显示可以分为多个节点,节点可以收缩也可以展开,当然节点

网络采集软件核心技术剖析系列(7)---如何使用C#语言搭建程序框架(经典Winform界面,顶部菜单栏,工具栏,左边树形列表,右边多Tab界面)

一 本系列随笔概览及产生的背景 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软件使用.NET技术开发,为回馈社区,现将该软件中用到的核心技术,开辟一个专栏,写一个系列文章,以飨广大技术爱好者. 本系列文章除了讲解网络采编发用到的各种重要技术之外,也提供了不少问题的解决思路和界面开发的编程经验,非常适合.NET开发的初级,中级读者,希望大家多多支持. 很多初学者常有此类困惑,“为

RDIFramework.NET V3.3 Web框架主界面新增横向菜单功能

功能描述 响应重多客户的要求与心声,RDIFramework.NET框架Web版本主界面新增横向菜单功能.横向菜单更加直观,用户可操作与展示的空间更多,符合实际应用要求. 一.效果展示 最终界面效果: 横向菜单效果图 动画展示效果: 横向菜单动画展示 二.加入方法 1."MenuIndex.cshtml"的文件在项目中的下面位置: 2.修改登录界面代码如下: 登录代码代码修改 3.主界面控制器新增代码如下: 4.修改个性化设置代码,加入横向菜单的设置,如下: 第4步的设置就是在&quo

常规功能和模块自定义系统 (cfcmms)—009主界面和菜单的展示和控制(1)

常规功能和模块自定义系统 (cfcmms)-009主界面和菜单的展示和控制(1) 先从主界面和菜单.主tab标签以及一些附加的设置说起. 一个比较传统的管理软件中,一般会包括一个顶部区域.底部区域.菜单条(树状菜单)和主操作区域.本系统亦是如此,只是增加了一点灵活控制的地方.首先来看看本系统中的界面布局和extjs的类之间的对应关系,extjs中的面象对象的功能已经比较完善了,现在开发b/s程序就和我以前用组件开发delphi系统差不多,建好一个个组件类,然后直接使用即可. 和主界面.菜单相关的