Winform开发框架之通用人员信息管理实现代码介绍

我在上一篇《Winform开发框架之通用人员信息管理》随笔中介绍了这个通用人员信息管理的大致实现界面和思路,本篇就其中的实现细节做进一步的分析和共享,希望大家对其中的实现代码进行一个了解,并希望多多提出宝贵意见。通用人员信息管理模块,这个模块其实在很多场合都可能用到,如企业员工管理、科室员工管理等等,这些要求登记人员详细资料及图片等信息的系统模块。

1、项目框架布局

以上几个模块分开是为了适应更多的项目需要,如可能用到WCF模块,那么实体类需要独立引用。但是如果是纯粹的Winform模块,以最少化项目为管理原则,那么就不需要那么多工程了,这样也方便项目的集成引用。虽然我们把基于多数据库支持的逻辑及数据库访问实现,封装到一个WHC.StaffData.Core项目里面,但是如果是Winform的项目应用,我们只需要引用他的代码路径就可以了,这样就保证了一份代码实体,多次外部应用的良好处理。如下所示。

这样的Winform模块整合后,我们在实际集成项目的时候,就很方便,人员管理模块就只有一个WHC.StaffDataDx程序集,不用管理太多关于人员模块的程序DLL了(否则有UI层、BLL层、DAL层、IDAL层、Entity层等等很多项目工程,这样一旦模块分的比较多,几十个就出来了,非常不便于管理)。

以上就是一个集成测试项目用到的相关应用,我们看到,人员管理模块里面只有一个程序集,其他的是人员管理模块用到的其他公用模块,这样比较方便管理,更利于大型项目的集成工作,不同的模块职责不同,维护可能也交由不同的技术人员维护即可,而且最大的优点是所有项目都通用,提高重复利用的效率。

集成测试项目是我们实际集成的参考例子,使用很简单,如下所示。

private void btnAddStaff_Click(object sender, EventArgs e)
        {
            FrmEditStaff dlg = new FrmEditStaff();
            dlg.ShowDialog();
        }

        private void btnStaffList_Click(object sender, EventArgs e)
        {
            FrmStaff dlg = new FrmStaff();
            dlg.ShowDialog();
        }

2、多数据库支持

整个小项目,是我Winform开发框架的缩影,我的Winform开发框架都基本上遵循一个规则来做各独立模块的开发,都具有多数据库支持的特性,良好的框架布局和高质量的代码特性。

我的传统Winform开发框架的设计图,如下所示。其中界面层UI直接访问BLL层,不需要通过网络,其中公用辅助类库Common层、实体类层可以在各个层中访问,并把常用的权限管理、字典管理封装为组件模块,直接调用,底层则使用工厂方式,来支持各种不同的数据库,其中UI层、BLL层、DAL层、实体层均使用继承类方式实现最良好的封装、最优的代码设计。

当然下面的框架示意图也是适用于这个人员管理模块的了。

实现多数据库支持的框架项目实际代码结构如下所示。

他们几个层之间的关系我在很早介绍框架数据库结构就介绍过,如下所示。

他们几个层之间的关系,具有非常强的继承关系,数据访问层有一个超级基类,抽象于各种数据库的基础上而形成,对于不同的数据库,还有一个一般的基类,用来实现详细化的数据库特性,每个业务类,明确继承关系后,就具有一份非凡的本领(具有几乎所有常用到的各类通用接口),很多时候我们基本不需要写任何和数据库操作的代码了。

3、界面实现

对于界面的设计,一直也希望能比较好的体现出我的设计思想,在整个人员信息管理中,有人员学习情况、履历情况、家庭情况、出国情况、职称情况等,界面基本上比较统一,就是一个列表的管理,常规的管理思路,一般还需要对列表的顺序可以自由调整,这是很常见的功能,因此,这里也引入了一个可以调整顺序的GridControlDrager 辅助类,这个就是在使用时,用户可以拖动记录到任意的顺序。

实现代码如下所示:

        private void StaffResumeControl_Load(object sender, EventArgs e)
        {
            if (!this.DesignMode)
            {
                GridControlDrager drager = new GridControlDrager(this.gridControl1);
                drager.ProcessDragRow += new GridControlDrager.ProcessEventHandler(drager_ProcessDragRow);
            }
        }

        bool drager_ProcessDragRow(int sourceRowHandle, int targetRowHandle)
        {
            DataTable table = this.gridControl1.DataSource as DataTable;
            if (table != null)
            {
                string sourceID = this.gridView1.GetRowCellValue(sourceRowHandle, "ID").ToString();
                string targetID = this.gridView1.GetRowCellValue(targetRowHandle, "ID").ToString();

                bool result = BLLFactory<StaffResume>.Instance.UpdateTwoSeq(sourceID, targetID);
                if (result)
                {
                    DataRow sourceRow = table.Rows[sourceRowHandle];

                    DataRow row = table.NewRow();
                    row.ItemArray = sourceRow.ItemArray;

                    table.Rows.Remove(sourceRow);
                    table.Rows.InsertAt(row, targetRowHandle);

                    this.gridControl1.DataSource = table;
                    this.gridView1.FocusedRowHandle = targetRowHandle;
                }
            }

            return true;
        }

几个模块大致的设计界面如下所示,然后在窗体里面集成就可以了。

 运行时刻的界面效果如下所示。

 以上还包含了附件的管理,这个模块在之前的《Winform开发框架之通用附件管理模块》有介绍,这里不再赘述了。

4、Word报表导出操作

上篇随笔介绍了Word导出的格式,导出的人员信息表如下所示:

我们看到,里面很多信息是单字段的,有部分是列表的,对于单字段,我们采用在模板中添加标签引用方式,然后替换其中的标签引用的文本实现,如下所示。

#region 通过书签方式替换内容
                Dictionary<string, string> dictBookMark = new Dictionary<string, string>();
                //姓名,性别,出生时间,政治面貌,党团时间,民族,籍贯,职务,任职时间,工作时间,最高学历,获学历时间,最高学位,
                //获学位时间,婚否,职称,职称时间,是否独生子女
                StaffInfo staffInfo = BLLFactory<Staff>.Instance.FindByID(ID);
                if (staffInfo != null)
                {
                    dictBookMark.Add("姓名", staffInfo.Name);
                    dictBookMark.Add("性别", staffInfo.Sex);
                    dictBookMark.Add("出生时间", staffInfo.BirthDate.GetDateTimeString("yyyy.MM.dd"));
                    dictBookMark.Add("政治面貌", staffInfo.Political);
                    dictBookMark.Add("党团时间", staffInfo.PartyDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("民族", staffInfo.Nationality);
                    dictBookMark.Add("籍贯", staffInfo.NativePlace);
                    dictBookMark.Add("职务", staffInfo.OfficialRank);
                    dictBookMark.Add("任职时间", staffInfo.ServingDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("工作时间", staffInfo.WorkingDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("最高学历", staffInfo.HighestEducation);
                    dictBookMark.Add("获学历时间", staffInfo.EducationDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("最高学位", staffInfo.HighestDegree);
                    dictBookMark.Add("获学位时间", staffInfo.DegreeDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("婚否", staffInfo.MarriageStatus);
                    dictBookMark.Add("职称", staffInfo.Titles);
                    dictBookMark.Add("职称时间", staffInfo.TitlesDate.GetDateTimeString("yyyy.MM"));
                    dictBookMark.Add("是否独生子女", staffInfo.ChildStatus);

                    StaffAwardInfo awardInfo = BLLFactory<StaffAward>.Instance.FindSingle(condition);
                    if (awardInfo != null)
                    {
                        dictBookMark.Add("受奖情况", awardInfo.Note);
                    }
                }

                Aspose.Words.Document doc = new Aspose.Words.Document(templateFile);
                foreach (string name in dictBookMark.Keys)
                {
                    Aspose.Words.Bookmark bookmark = doc.Range.Bookmarks[name];
                    if (bookmark != null)
                    {
                        bookmark.Text = dictBookMark[name];
                    }
                }
                #endregion

对于列表的内容,我们就要引入Aspose.Word的MailMerge功能了,先在固定模板中插入并定义好相关的域引用,如下所示。

创建一系列的域代码引用后,才能利用Aspose.Word的MailMerge功能。

上图红色部分为对于一个列表必须要创建的域代码,包括TableStart:和TableEnd的标识。

创建好这些后,绑定数据源的操作不算复杂,如下所示。

                Aspose.Words.DocumentBuilder builder = new Aspose.Words.DocumentBuilder(doc);

                List<StaffStudyInfo> studyList = BLLFactory<StaffStudy>.Instance.Find(condition);
                DataTable dtStudy = DataTableHelper.ToDataTable<StaffStudyInfo>(studyList);
                dtStudy.TableName = "study";
                FillStaticRow(dtStudy, 5);

                List<StaffTitlesInfo> titleList = BLLFactory<StaffTitles>.Instance.Find(condition);
                DataTable dtTitle = DataTableHelper.ToDataTable<StaffTitlesInfo>(titleList);
                dtTitle.TableName = "title";
                FillStaticRow(dtTitle, 5);

.....................

                DataSet ds = new DataSet();
                ds.Tables.Add(dtStudy);
                ds.Tables.Add(dtTitle);
                ds.Tables.Add(dtResume);
                ds.Tables.Add(dtAbroad);
                ds.Tables.Add(dtFamily);

                doc.MailMerge.ExecuteWithRegions(ds);                

                doc.Save(saveFile);

                if (MessageDxUtil.ShowYesNoAndTips("导出成功,是否打开文件?") == System.Windows.Forms.DialogResult.Yes)
                {
                    Process.Start(saveFile);
                }

其中的FillStaticRow函数,我是用来生成固定怎么多行的操作,使得列表默认不少于固定的函数,否则列表不好看。

以上就是我在开发这个模块中的一些经验心得,希望抛砖引玉,对大家有帮助的同时,也能获得更多的反馈意见,相互促进交流。

本文转自博客园伍华聪的博客,原文链接:Winform开发框架之通用人员信息管理实现代码介绍,如需转载请自行联系原博主。

时间: 2024-10-17 09:41:07

Winform开发框架之通用人员信息管理实现代码介绍的相关文章

Winform开发框架之通用人员信息管理

我在随笔<Winform开发框架之通用短信邮件通知模块>和<Winform开发框架之通用附件管理模块>等多篇文章中都有介绍我总体的一个Winform开发框架的规划,其实就是开发一个集成度高的Winform开发框架,然后尽可能开发一些日常项目用到的模块,我称之为通用模块(可重复利用,或稍微调整可以适应项目需求),这样就形成了一个良好的生态体系,能够极快提高开发效率,同时也能规范化项目产品的开发工作,松耦合的集成能提供更高层的整合和利用.本文主要介绍我的Winform开发框架体系里面的

Winform开发框架之通用定时服务管理2---如何开发定时服务应用

在上篇随笔<Winform开发框架之通用定时服务管理>介绍了我的框架体系中,通用定时服务管理模块的设计以及一些相关功能的展示.我们在做项目的时候,或多或少需要和其他外部系统或者接口进行数据交互,有些是单向的获取,有些是双向的操作.这个定时操作(可能是间隔的时间,也可以能是定在某一个时刻,也可以能是让它在某天某时刻运行),那么这就需要定时服务程序来管理了,通常我们把他寄宿在Windows服务里面(这也是一种最佳的方式),这种方式最好的地方,就是它的生命周期可以随着电脑的启动而启动,而且很少需要用

Winform开发框架之通用定时服务管理

做项目的时候,或多或少需要和其他外部系统或者接口进行数据交互,有些是单向的获取,有些可能是修改状态后再写回去,不管如何,这个都可以称之为数据同步操作,如人员信息同步.业务数据同步.第三方接口数据同步等等. 数据同步涉及到一个同步时间的问题,一般不敏感的数据,一天或者一周左右同步一次就可以了,有些可能需要间隔更短一点. 同步的逻辑不同,有些可能写数据库就可以了,有些可能需要访问WebService或者其他接口,然后在进行数据获取,保存等操作,回写的时候,也一般是调用WebService这样的接口修

Winform开发框架之通用附件管理模块

在做Winform项目的时候,一直有一个梦想,就是希望把所有的组件模块组合即可组装成一个完整的项目系统(或者至少可以大部分完成).这即使是梦想,我也一直为之奋斗,每前进一步,我们离梦想就靠近一步.因此,本着这个梦想,我一路走来,开发整理了一系列的组件模块,包括底层的公用类库.Winform分页控件.通用的适应多数据库的查询组件,以及相对高层次一点的组件模块:通用权限管理系统.通用字典管理模块.通用程序自动更新模块.以及本篇随笔介绍的通用附件管理模块,当然还会有更多的组件模块会吸引我继续朝着梦想前

Winform开发框架之通用数据导入导出操作的事务性操作完善

1.通用数据导入导出操作模块回顾 在我的Winfrom开发框架里面,有一个通用的导入模块,它在默默处理这把规范的Excel数据导入到不 同的对象表里面,一直用它来快速完成数据导入的工作.很早在随笔<Winform开发框架之通用数据导入 导出操作>里面就很全面的介绍过它的相关功能了,在代码生成工具Database2Sharp里面,生成的 Winfrom界面代码也已经把它的调用代码放进去了,因此使用起来真是很好,很开心. 在不断的项目实践中,发现使用基于Sqlite的客户端作为单机版的操作也越来越

Winform开发框架之通用高级查询模块

最近一直忙于公司的事情,虽然一直在做一些相关的技术研究,但是很久没能静下心来好好写写博客文章了,想想也有半个月之多了,这半个月来,也一直致力于改善我的WInform开发框架,使得自己及客户使用起来更加方便,更加友好,更加高效.本篇文章就是介绍最近框架改善的其中一个闪光点"通用高级查询模块",高级查询模块,在很多程序模块中都很常见,也是给客户扩展查询的一个很好的补充,由于我一直希望我的Winform开发框架能够精益求精,所以做了这个模块,希望对今后我自己所有的项目以及框架本身,都能高效的

Winform开发框架之通用数据导入导出操作

做了很多Winform的项目,对于数据导入,一直也有自己的理解,由于一般的业务系统,经常性的数据导入时很正常的业务需求,因为毕竟使用Excel来操作数据也很方便,或者由于系统之间的数据交换需要,我们需要提供一个入口给客户导入所需要的数据.但是导入数据的时候,不同的业务数据对应不同的Excel文件,很难做到统一,但如果是每个业务模型,都创建一个不同的导入界面来操作Excel数据,又会觉得可能某种程度上重复劳动,增加开发及维护成本. 那么有无一种介于两者之间的方法,来实现效率的最优化,并且能够统一利

Winform开发框架之通用短信邮件通知模块

在做Winform项目的时候,一直有一个梦想,就是希望把所有的组件模块组合即可组装成一个完整的项目系统(或者至少可以大部分完成).在之前介绍的<Winform开发框架之通用附件管理模块>里面介绍了我的Winform开发框架的版图,里面包含了我对Winform模块化的一系列规划的组件,组件尽可能是适用于大多数的业务环境组合,以达到最大程度的重用和高效开发. Winform开发框架是我集多年开发经验以及积累而成,很多细节之处润物细无声,但却是精粹心得所至,很多地方都希望是精益求精,力求把框架中的模

Winform开发框架之通用自动更新模块

在网络化的环境中,特别是基于互联网发布的Winform程序,程序的自动更新功能是比较重要的操作,这样可以避免挨个给使用者打电话.发信息通知或者发送软件等,要求其对应用程序进行升级.实现程序的自动更新,在后期发布维护过程中,一个可以快速相应修正相关的Bug或者增加功能,二个可以避免给使用客户隔三差五的发送修改好的程序,省心省力.本文也是基于这个思想,在Winform开发框架中再引入一个自动升级更新的通用模块,这个自动升级的通用模块除了具备一般的功能外,可以通过配置程序标题.升级路径方式等方式,实现