在做工控上位机项目时,当项目过于庞大,细分的流程就很多,需要管理的页面也就会增加很多,这时可以使用.NET控件TreeView进行页面的切换管理,并且实现TreeView间的互相切换。Intouch和Wonderware可以导入并使用TreeView控件。
一、使用VS开发TreeView控件
创建一个控件项目解决方案
拖一个TreeView控件,可以简单的进行节点编辑
Tag是需要向外传递的数据
二、出现的问题
在项目后期,对方会提出很多的改进需求,这时如果一个项目中存在过多的TreeView控件,每次改进,对于上位机系统来说就需要重新导入一次,重复过程太多,太繁琐。
解决方案:在数据库中创建菜单表,项目运行时菜单栏自动生成
三、创建数据库
创建数据库表,MenuId是菜单序号,MenuName为TreeView显示的页面名称,MenuCode为Tag,ParentId为该子节点的根节点
四、编写代码自动生成
按照两层架构来完成
实体类TreeViewNode
1 public class TreeViewNode 2 { 3 public int MenuId { get; set; } 4 5 public string MenuName { get; set; } 6 7 public string MenuCode { get; set; } 8 9 public string ParentId { get; set; } 10 }
Service层:MenuService
1 /// <summary> 2 /// 获取所有的菜单子项 3 /// </summary> 4 /// <returns></returns> 5 public List<TreeViewNode> GetAllMenu() 6 { 7 string sql = "select MenuId,MenuName,MenuCode,ParentId from MenuList"; 8 List<TreeViewNode> nodeList = new List<TreeViewNode>(); 9 SqlDataReader objRead = SQLHelper.GetReader(sql); 10 while (objRead.Read()) 11 { 12 nodeList.Add(new TreeViewNode() 13 { 14 MenuId = Convert.ToInt32(objRead["MenuId"]), 15 MenuName = objRead["MenuName"].ToString(), 16 MenuCode = objRead["MenuCode"].ToString(), 17 ParentId = objRead["ParentId"].ToString() 18 }); 19 } 20 objRead.Close(); 21 return nodeList; 22 }
TreeViewMenu控件:
1 public partial class TreeViewMenu: UserControl 2 { 3 public TreeViewMenu() 4 { 5 InitializeComponent(); 6 LoadTreeViewMenu(); 7 } 8 9 private List<TreeViewNode> nodeList = null; 10 private MenuService menuService = new MenuService(); 11 private string _currentnodename; 12 //加载树形菜单 13 private void LoadTreeViewMenu() 14 { 15 this.nodeList = menuService.GetAllMenu(); 16 17 //创建一个根节点 18 this.TreeView_MenuList.Nodes.Clear(); 19 TreeNode rootNode = new TreeNode(); 20 rootNode.Text = "测试"; 21 rootNode.Tag = "0"; 22 this.TreeView_MenuList.Font = new Font(this.TreeView_MenuList.Font.FontFamily, 11); 23 rootNode.NodeFont = new Font("微软雅黑", 11.5f, FontStyle.Bold); 24 //rootNode.ImageIndex = 0;//设置根节点显示的图片 25 this.TreeView_MenuList.Nodes.Add(rootNode);//将根节点添加到TreeView节点中 26 27 //基于递归方式添加所有子节点 28 CreateChildNode(rootNode, "0"); 29 this.TreeView_MenuList.Nodes[0].Expand();//将树的一级节点展开 30 } 31 private void CreateChildNode(TreeNode parentNode, string preld) 32 { 33 //找到以所有该节点为父节点的子项 34 var nodes = from list in this.nodeList where list.ParentId.Equals(preld) select list; 35 //循环创建该节点的子节点 36 foreach (var item in nodes) 37 { 38 //创建新的节点并设置属性 39 TreeNode node = new TreeNode(); 40 node.Text = item.MenuName; 41 node.Tag = item.MenuCode; 42 //设置节点图标 43 if (item.ParentId == "0") 44 { 45 //node.ImageIndex = 1; 46 node.NodeFont = new Font("微软雅黑", 10.5f, FontStyle.Bold); 47 } 48 else 49 { 50 node.NodeFont = new Font("微软雅黑", 10.5f); 51 //node.ImageIndex = 3; 52 } 53 parentNode.Nodes.Add(node);//父节点加入该子节点 54 //使用递归实现子节点的添加 55 CreateChildNode(node, item.MenuId.ToString()); 56 } 57 } 58 private void TreeView_MenuList_AfterSelect(object sender, TreeViewEventArgs e) 59 { 60 _currentnodename = e.Node.Tag != null ? e.Node.Tag.ToString() : _currentnodename; 61 } 62 public string CurrentNode 63 { 64 get { return _currentnodename; } 65 set { _currentnodename = value; } 66 } 67 }
运行调试一下,菜单完美的自动生成。
把生成的TreeViewMenu.dll导入进Intouch和Wonderware即可使用
五、后期修改完善
以后修改菜单,只需在数据库中增删改即可,不必每次都重新导入控件。
并且这个控件只需要开发一次,就可以重复的导入不同的项目中,只需在数据库中配置菜单信息即可。