在上篇总结随笔《Winform开发框架之权限管理系统改进的经验总结()TreeListLookupEdit控件的使用》介绍了权限管理模块的用户管理部分其中主要介绍了其中的用户所属公司所属部门直属经理(人员列表)的几级数据级联的展示通过引入TreeListLookupEdit控件能增强用户的体验效果本篇继续介绍权限系统模块中的一些闪光点介绍组织机构管理里面选择用户的界面设计和实现用户选择在很多场合会用到如组织机构的用户选择角色里面的用户选择或者流程里面的用户选择等用途 选择用户界面效果展示用户选择在很多地方需要用到本篇以组织机构里面的用户选择为例介绍用户选择的界面效果我们知道用户一般可以按组织机构进行分类也可以按照角色进行分类因此我们需要结合两者进行快速展示用户的层次关系界面效果如下所示 在上面的界面分为三个部分左边主要是机构和角色的展示右边则是通过列表控件进行展示并可以进行勾选的操作底部则是已选用户的列表展示(可以移除) 左边机构树的递归展现组织机构本身设计就是一个有层次关系的树因此它可以通过递归函数进行展现展示方式可以使用传统样式的TreeView控件或者DevExpress样式的TreeList控件不过我倾向于使用TreeView觉得这个线状的层次关系更美观一些递归展示结构树的代码如下所示 private void InitDeptTree() { thistreeDeptBeginUpdate(); thistreeDeptNodesClear(); TreeNode node = new TreeNode(); nodeText = 所有部门; List<OUNodeInfo> list = BLLFactory<OU>InstanceGetTree(); AddDept(list node); thistreeDeptNodesAdd(node); thistreeDeptExpandAll(); thistreeDeptEndUpdate(); } private void AddDept(List<OUNodeInfo> list TreeNode treeNode) { foreach (OUNodeInfo ouInfo in list) { TreeNode deptNode = new TreeNode(); deptNodeText = ouInfoName; deptNodeTag = ouInfoID; deptNodeImageIndex = PortalgcGetImageIndex(ouInfoCategory); deptNodeSelectedImageIndex = PortalgcGetImageIndex(ouInfoCategory); treeNodeNodesAdd(deptNode); AddDept(ouInfoChildren deptNode); } } 角色树不是一个递归的关系因此只需要按列表展示即可展示代码如下所示
private void InitRoleTree() { thistreeRoleBeginUpdate(); thistreeRoleNodesClear(); TreeNode node = new TreeNode(); nodeText = 所有角色; List<RoleInfo> list = BLLFactory<Role>InstanceGetAll(); foreach (RoleInfo info in list) { TreeNode roleNode = new TreeNode(); roleNodeText = infoName; roleNodeTag = infoID; roleNodeImageIndex = ; roleNodeSelectedImageIndex = ; nodeNodesAdd(roleNode); } thistreeRoleNodesAdd(node); thistreeRoleExpandAll(); thistreeRoleEndUpdate(); } 角色列表大概效果如下所示 右边可勾选列表的实现右边其实可以通过一般的GridView进行展示但为了更好的封装和使用我使用我的Winform分页控件中的WinGridview对象进行展示这样使用起来更简便 public partial class FrmSelectUser : BaseForm { public FrmSelectUser() { InitializeComponent(); thiswinGridViewShowCheckBox = true; thiswinGridViewShowExportButton = false; thiswinGridViewShowLineNumber = true; thiswinGridViewBestFitColumnWith = false;//是否设置为自动调整宽度false为不设置 thiswinGridViewOnRefresh += new EventHandler(winGridView_OnRefresh); thiswinGridViewgridViewDataSourceChanged += new EventHandler(gridView_DataSourceChanged); if (!thisDesignMode) { InitDeptTree(); InitRoleTree(); } } 绑定数据是通过左边的树进行条件检索的因此可以通过获取组织机构或者角色的节点数据进行查询我们通过判断组织机构树节点或者角色树节点是否选中来判断即可具体列表绑定的代码如下所示 private void BindGridData() { List<UserInfo> list = new List<UserInfo>(); if (thistreeDeptSelectedNode != null && thistreeDeptSelectedNodeTag != null) { int ouId = thistreeDeptSelectedNodeTagToString()ToInt(); list = BLLFactory<User>InstanceFindByDept(ouId); } else if (thistreeRoleSelectedNode != null && thistreeRoleSelectedNodeTag != null) { int roleId = thistreeRoleSelectedNodeTagToString()ToInt(); list = BLLFactory<User>InstanceGetUsersByRole(roleId); } //entity thiswinGridViewDisplayColumns = HandNoNameFullNameTitleMobilePhoneOfficePhoneEmailGenderQQNote; thiswinGridViewColumnNameAlias = BLLFactory<User>InstanceGetColumnNameAlias();//字段列显示名称转义 thiswinGridViewDataSource = new WHCPagerWinControlSortableBindingList<UserInfo>(list); } 单用户勾选列表的复选框的时候该行的数据会被选中我们最后要获取用户的勾选记录(通过WinGridview控件的GetCheckedRows方法获取)然后获取对应的数据添加到关联关系的数据库即可具体代码如下所示
private void btnAddUser_Click(object sender EventArgs e) { List<int> list = thiswinGridViewGetCheckedRows(); foreach(int rowIndex in list) { string ID = thiswinGridViewGridViewGetRowCellDisplayText(rowIndex ID); string Name= thiswinGridViewGridViewGetRowCellDisplayText(rowIndex Name); string FullName = thiswinGridViewGridViewGetRowCellDisplayText(rowIndex FullName); string displayname = stringFormat({}({}) FullName Name); if (!thisSelectUserDictContainsKey(ID)) { thisSelectUserDictAdd(ID displayname); } } RefreshSelectItems(); } 用户选择结果的展示在一些场景中我们可能需要在多个组织机构和角色中选择不同的用户为了更方便展示我们选中的记录我设计了一个用户控件(一个删除按钮(Button)+标签控件(Lable))组合即可如下所示 由于我们选择的内容无非就是选择它的人员名称即可如果需要单击删除按钮让用户剔除不需要的人员因此控件增加一个OnDeleteItem事件用来处理这个删除操作 我们展示多个用户信息的时候就是通过构造多个这样的控件并动态增加到Panel里面即可实现代码如下所示 /// <summary> /// 刷新选择信息 /// </summary> private void RefreshSelectItems() { thisflowLayoutPanelControlsClear(); foreach (string key in SelectUserDictKeys) { string info = SelectUserDict[key]; if (!stringIsNullOrEmpty(info)) { UserNameControl control = new UserNameControl(); controlBindData(key info); controlOnDeleteItem += new UserNameControlDeleteEventHandler(control_OnDeleteItem); thisflowLayoutPanelControlsAdd(control); } } thislblItemCountText = stringFormat(当前选择【{}】项目 SelectUserDictKeysCount); } 最终的组织机构管理界面效果在开篇说了用户选择在很多场合会用到如组织机构的用户选择角色里面的用户选择或者流程里面的用户选择等用途 下面是组织机构里面的主体界面 在右上角的包含用户区域单击添加按钮就会出现前面说到的用户选择对话框如下所示 伍华聪 |