zoukankan      html  css  js  c++  java
  • Winform开发框架之权限管理系统改进的经验总结(2)-用户选择界面的设计

    在上篇总结随笔《Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用》介绍了权限管理模块的用户管理部分,其中主要介绍了其中的用户所属公司、所属部门、直属经理(人员列表)的几级数据级联的展示,通过引入TreeListLookupEdit控件,能增强用户的体验效果。本篇继续介绍权限系统模块中的一些闪光点,介绍组织机构管理里面选择用户的界面设计和实现,用户选择在很多场合会用到,如组织机构的用户选择,角色里面的用户选择,或者流程里面的用户选择等用途。

    1、选择用户界面效果展示

    用户选择在很多地方需要用到,本篇以组织机构里面的用户选择为例,介绍用户选择的界面效果。我们知道,用户一般可以按组织机构进行分类,也可以按照角色进行分类,因此我们需要结合两者进行快速展示用户的层次关系,界面效果如下所示。

    在上面的界面分为三个部分:左边主要是机构和角色的展示;右边则是通过列表控件进行展示,并可以进行勾选的操作;底部则是已选用户的列表展示(可以移除)。

    2、左边机构树的递归展现

    组织机构本身设计就是一个有层次关系的树,因此它可以通过递归函数进行展现,展示方式可以使用传统样式的TreeView控件或者DevExpress样式的TreeList控件,不过我倾向于使用TreeView,觉得这个线状的层次关系更美观一些,递归展示结构树的代码如下所示。

            private void InitDeptTree()
            {
                this.treeDept.BeginUpdate();
                this.treeDept.Nodes.Clear();            
    
                TreeNode node = new TreeNode();
                node.Text = "所有部门";   
    
                List<OUNodeInfo> list = BLLFactory<OU>.Instance.GetTree();        
                AddDept(list, node);
    
                this.treeDept.Nodes.Add(node);
                this.treeDept.ExpandAll();
                this.treeDept.EndUpdate();
            }
    
            private void AddDept(List<OUNodeInfo> list, TreeNode treeNode)
            {
                foreach (OUNodeInfo ouInfo in list)
                {
                    TreeNode deptNode = new TreeNode();
                    deptNode.Text = ouInfo.Name;
                    deptNode.Tag = ouInfo.ID;
                    deptNode.ImageIndex = Portal.gc.GetImageIndex(ouInfo.Category);
                    deptNode.SelectedImageIndex = Portal.gc.GetImageIndex(ouInfo.Category);
                    treeNode.Nodes.Add(deptNode);
    
                    AddDept(ouInfo.Children, deptNode);
                }
            }

    角色树不是一个递归的关系,因此只需要按列表展示即可,展示代码如下所示。

            private void InitRoleTree()
            {
                this.treeRole.BeginUpdate();
                this.treeRole.Nodes.Clear();
    
                TreeNode node = new TreeNode();
                node.Text = "所有角色";
    
                List<RoleInfo> list = BLLFactory<Role>.Instance.GetAll();
                foreach (RoleInfo info in list)
                {
                    TreeNode roleNode = new TreeNode();
                    roleNode.Text = info.Name;
                    roleNode.Tag = info.ID;
                    roleNode.ImageIndex = 5;
                    roleNode.SelectedImageIndex = 5;
    
                    node.Nodes.Add(roleNode);
                }
    
                this.treeRole.Nodes.Add(node);
                this.treeRole.ExpandAll();
                this.treeRole.EndUpdate();
            }

    角色列表大概效果如下所示。

    3、右边可勾选列表的实现

    右边其实可以通过一般的GridView进行展示,但为了更好的封装和使用,我使用我的Winform分页控件中的WinGridview对象进行展示,这样使用起来更简便。

        public partial class FrmSelectUser : BaseForm
        {
            public FrmSelectUser()
            {
                InitializeComponent();
    
                this.winGridView1.ShowCheckBox = true;
                this.winGridView1.ShowExportButton = false;
                this.winGridView1.ShowLineNumber = true;
                this.winGridView1.BestFitColumnWith = false;//是否设置为自动调整宽度,false为不设置
                this.winGridView1.OnRefresh += new EventHandler(winGridView1_OnRefresh);
                this.winGridView1.gridView1.DataSourceChanged += new EventHandler(gridView1_DataSourceChanged);
    
                if (!this.DesignMode)
                {
                    InitDeptTree();
                    InitRoleTree();
                }
            }

    绑定数据是通过左边的树进行条件检索的,因此可以通过获取组织机构或者角色的节点数据进行查询,我们通过判断组织机构树节点或者角色树节点是否选中来判断即可,具体列表绑定的代码如下所示。

            private void BindGridData()
            {
                List<UserInfo> list = new List<UserInfo>();
                if (this.treeDept.SelectedNode != null && this.treeDept.SelectedNode.Tag != null)
                {
                    int ouId = this.treeDept.SelectedNode.Tag.ToString().ToInt32();
                    list = BLLFactory<User>.Instance.FindByDept(ouId);
                }
                else if (this.treeRole.SelectedNode != null && this.treeRole.SelectedNode.Tag != null)
                {
                    int roleId = this.treeRole.SelectedNode.Tag.ToString().ToInt32();
                    list = BLLFactory<User>.Instance.GetUsersByRole(roleId);
                }
    
                //entity
                this.winGridView1.DisplayColumns = "HandNo,Name,FullName,Title,MobilePhone,OfficePhone,Email,Gender,QQ,Note";
                this.winGridView1.ColumnNameAlias = BLLFactory<User>.Instance.GetColumnNameAlias();//字段列显示名称转义
    
                this.winGridView1.DataSource = new WHC.Pager.WinControl.SortableBindingList<UserInfo>(list);
            }

    单用户勾选列表的复选框的时候,该行的数据会被选中,我们最后要获取用户的勾选记录(通过WinGridview控件的GetCheckedRows方法获取),然后获取对应的数据,添加到关联关系的数据库即可,具体代码如下所示。

            private void btnAddUser_Click(object sender, EventArgs e)
            {
                List<int> list = this.winGridView1.GetCheckedRows();
                foreach(int rowIndex in list)
                {
                    string ID = this.winGridView1.GridView1.GetRowCellDisplayText(rowIndex, "ID");
                    string Name= this.winGridView1.GridView1.GetRowCellDisplayText(rowIndex, "Name");
                    string FullName = this.winGridView1.GridView1.GetRowCellDisplayText(rowIndex, "FullName");
                    string displayname = string.Format("{0}({1})", FullName, Name);
    
                    if (!this.SelectUserDict.ContainsKey(ID))
                    {
                        this.SelectUserDict.Add(ID, displayname);
                    }
                }
    
                RefreshSelectItems();
            }

    4、用户选择结果的展示

    在一些场景中,我们可能需要在多个组织机构和角色中选择不同的用户,为了更方便展示我们选中的记录,我设计了一个用户控件(一个删除按钮(Button)+标签控件(Lable))组合即可,如下所示。

    由于我们选择的内容,无非就是选择它的人员名称即可,如果需要,单击删除按钮,让用户剔除不需要的人员,因此控件增加一个OnDeleteItem事件用来处理这个删除操作。

    我们展示多个用户信息的时候,就是通过构造多个这样的控件,并动态增加到Panel里面即可,实现代码如下所示。

            /// <summary>
            /// 刷新选择信息
            /// </summary>
            private void RefreshSelectItems()
            {
                this.flowLayoutPanel1.Controls.Clear();
                foreach (string key in SelectUserDict.Keys)
                {
                    string info = SelectUserDict[key];
                    if (!string.IsNullOrEmpty(info))
                    {
                        UserNameControl control = new UserNameControl();
                        control.BindData(key, info);
                        control.OnDeleteItem += new UserNameControl.DeleteEventHandler(control_OnDeleteItem);
                        this.flowLayoutPanel1.Controls.Add(control);
                    }
                }
                this.lblItemCount.Text = string.Format("当前选择【{0}】项目", SelectUserDict.Keys.Count);
            }

    5、最终的组织机构管理界面效果

    在开篇说了,用户选择在很多场合会用到,如组织机构的用户选择,角色里面的用户选择,或者流程里面的用户选择等用途。

    下面是组织机构里面的主体界面。

    在右上角的包含用户区域,单击添加按钮,就会出现前面说到的用户选择对话框,如下所示。

  • 相关阅读:
    startActivity与startActivityForResult的使用小结
    http协议总结
    Activity的生命周期
    Android studio无法更新 提示网络连接失败
    微博OpenAPI练习之问题记录
    禁用menu键
    Activity与Fragment之间的通信
    Fragment生命周期
    Grafana采用Prometheus数据源监控linux服务器学习篇二
    Grafana采用Prometheus数据源监控linux服务器学习篇一
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/3493137.html
Copyright © 2011-2022 走看看