本人供职于国内一家比较知名的物流公司,一直从事于基层公司物流软件的规划和设计开发工作,在长期的工作实践中深深地体会到作为不是专业的软件行业而又从事软件开发行业的业余性的软件开发设计人员来说,在工作中需要克服的困难和面对的艰辛有多大多难。
对与专业的软件开发设计公司来说,毋庸置疑的一点是都会有自己成熟稳定的开发框架和组件,并且是在不断的完善中,对供职其中的开发设计人员在完成业务性的开发设计工作外日常工作的一个重心就在于了解、熟悉进而创新性的完善他。作为软件开发设计人员都知道,任何一个软件系统都离不开用户管理、权限管理等做为核心存在的基本功能,而这仅是上述所说成熟稳定的开发框架和组件的其中一部分。正因为有了成熟稳定开发框架和组件,设计开发人员并不需要去重新构建,从效率和易用性的考虑这节省了大量的开发时间,并且框架强制使用公共的约定,因此它能有效地解决一些共有的问题,也能避免我们写一大堆自定义模块来实现这些性能,我们所需要做的就是将这些共用模块放在框架中实现。框架节省了我们不少的时间和精力,并且让扩展变得更容易。
以上作为抛砖引玉,现在回到正题。近期考虑为公司(本人供职的基层公司,以下所称的公司均同此)构建一个仓库管理方面的信息系统。在此之前,基于自己的爱好和公司实际业务的需要,曾经多次尝试利用自己所学(2011年开始接触学习C#)的技术来构建一个相对稳定成熟的业务系统,以满足自己的“虚荣心”和公司业务的实际需要,也尝试过使用一些第三方的开源的技术和框架,可一直没有能找到一个相对稳定且开发快捷的途径,大量的时间浪费在寻找框架工具和核心基础功能上,不光花费了大量的时间,所开发的代码无论质量还是执行效率都不尽人意,且代码无所谓干净清晰,估计现在让我自己读起来都有些费劲。
其实算起来从最初接触《走火入魔权限管理系统》是在2012年了,那个时候接触的还是网上免费的V3.2的版本,随着这几年来软件作者的持续改进,代码质量和功能日趋完善。到2013年11月,当V4.0版本出来时,感觉到了软件的强大和对自己日后工作学习的帮助,毅然以个人名义定购了源码(呵呵,花的是个人的MONEY,虽然当时有点肉痛,不过经过近半年的接触学习,觉得还是物有所值的)。
在接触到新源码后,不到一星期就开始准备以一个简单进销存为业务蓝本着手,抱着在实践中学习,在学习中完善的心态开始开发练习。当然这是在对作者代码质量和核心功能(用户权限管理)充分认可的基础上才可行的。由于作者的源码已经包含了所有的关于用户以及权限的核心功能,所以在开始开发时我基本上都没考虑这方面的开发(要知道这个可是我以前花了近两年的时间也没有总结出来的经验,现在有现成的哪能不拿来就用呢,何况功能还那么强大),直接就以业务蓝本着手,开始规划业务流程、数据库设计、界面设计(基本上也都是参考),并开始编码。说到编码,作者也充分考虑到了代码的规范性的要求,提供了一个通用的代码生成工具,系统所需要的基本功能在设计好数据库的基础上一键生成,极大的提高了代码开发的质量和效率,而且所生成的代码可读性更强、效率更高、更易被其他软件开发者所接受,要实现稍微复杂一点的业务逻辑也只需要少量代码的改变就能完成。整个《进销存业务系统》从设计到开发,真正的代码开发(含数据库建表、界面开发)不到1月的时间。
以下是开发实例:
界面主页面实现左栏手风琴菜单,先看效果:
实现步骤:
1、 在主页面上拖入一个DX的navbarcontrol控件,排好版,参数默认
2、编写核心代码:
3、 private void Link_ItemClick(object sender, NavBarLinkEventArgs e)
4、 {
5、 ShowForm((NavBarItem)sender);
6、 }
7、
8、 #region private void LoadTreeModule(TreeNode treeNode) 加载模块菜单
9、 /// <summary>
10、 /// 加载模块菜单
11、 /// </summary>
12、 /// <param name="group">当前节点</param>
13、 private void LoadModule(List<BaseModuleEntity> moduleEntities, NavBarGroup group)
14、 {
15、 int i = 0;
16、 foreach (BaseModuleEntity moduleEntity in moduleEntities) //以每个子菜单做循环
17、 {
18、 if (moduleEntity.ParentId == int.Parse(group.Name.Trim()))
19、 {
20、 NavBarItem groupItem = new NavBarItem(); //为每个子菜单创建新item,构造体中传递子菜单名,和子菜单ID
21、 groupItem.LargeImageIndex = groupItem.SmallImageIndex = string.IsNullOrEmpty(moduleEntity.ImageIndex) ? i : int.Parse(moduleEntity.ImageIndex);
22、 groupItem.Caption = moduleEntity.FullName;
23、 groupItem.Tag = moduleEntity.FormName;
24、 groupItem.Hint = moduleEntity.AssemblyName;
25、 groupItem.LinkClicked += Link_ItemClick;
26、 group.ItemLinks.Add(groupItem); //在每个组里添加子菜单
27、
28、 i += 1;
29、 }
30、 }
31、 }
32、 #endregion
33、
34、
35、 #region private void LoadTree() 加载树形结构数据
36、 /// <summary>
37、 /// 加载树形结构数据
38、 /// </summary>
39、 private void LoadTree()
40、 {
41、 this.navBarControl1.Groups.Clear();//清空控件的值
42、
43、 // 这里是需要加载的跟节点主键
44、 int? rootMenuId = null;
45、 int i = 0;
46、
47、 DotNetService dotNetService = new DotNetService();
48、 List<BaseModuleEntity> moduleEntitys = ClientPermissionCache.Instance.UserModuleList;
49、
50、 rootMenuId = 10005235;
51、 foreach (BaseModuleEntity moduleEntity in moduleEntitys)
52、 {
53、 //~这部分可以单独调优,只是为了把左侧功能栏项加载好,要新增项只需修改判断条件。
54、 //if (string.IsNullOrEmpty(dr[BaseModuleEntity.FieldParentId].ToString()))
55、 if (moduleEntity.ParentId == rootMenuId)
56、 {
57、 //添加Group
58、
59、 NavBarGroup group = navBarControl1.Groups.Add(); // 为每个主菜单创建个新分组
60、 group.Caption = moduleEntity.FullName;
61、 group.LargeImageIndex = group.SmallImageIndex = string.IsNullOrEmpty(moduleEntity.ImageIndex) ? i : int.Parse(moduleEntity.ImageIndex);// Convert.ToInt32(row[BaseModuleTable.FieldImageIndex]);
62、 group.Tag = moduleEntity.Target;
63、 group.Name = moduleEntity.Id.ToString();
64、 i += 1;
65、
66、 LoadModule(moduleEntitys, group);
67、
68、 }
69、 }
70、 }
71、 #endregion
记得在初始化窗体时调用就OK了。调用的代码:this.LoadTree();
以下是系统销售订单主界面