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

1、通用高级查询模块的用途及介绍

既然称之为通用查询模块,那么他就不能与具体的表字段有耦合关系,但是要实现具体的查询,必须通过某种方式进行属性传递,实现更直观友好的字段查询功能。高级查询模块,在很多完善的程序上都会提供,用于满足用户对特定的字段,添加特定的条件进行,因为一般情况下,由于版面的限制界面上查询的内容比较有限,只是把一些很常见、重要的字段作为查询输入,如果表字段比较多,那么对有些特殊的字段就无所适从。

例如,我一个病人资料管理系统的界面如下所示

这个界面已经放置的比较多输入控件进行查询了,如果放置更多,超过3行就会导致感觉比较臃肿了。所以合理的应该是把不常用的放到高级查询里面,这样用户需要更多条件的定制,可以在高级查询中对每个字段都能进行搜索,常规的在主界面即可查询。

我的高级查询查询模块也是基于这个道理,因此,在主界面增加一个高级查询按钮入口,如上图所示,单击后,显示一个所有字段的列表,如下界面。

这样所有表的字段均可进行查询了,但是我们注意到,这个界面并没有输入条件的地方,没错,这个只是显示条件内容,浮在主界面的查询列表上面,如果设置条件后,主界面的列表会根据高级查询条件进行查询,这样也是符合客户实际的期望的。

在介绍输入条件的时候,我们注意到,查询输入,基本上可以分为几类:其一是常规的文本类型,使用文本框替代即可;其二是下拉列表类型,用户从列表下面选择内容;其三是日期类型,需要用户指定开始日期和结束日期;其四是数字类型,需要用户指定起始和结束的数值。

刚才说到,上面的高级查询界面,只是显示,但用户双击列表或者按下回车键,那么根据字段类型,弹出对应上面说到的四种输入框,用于接收用户的输入。

1)常规的文本类型条件输入界面:

下拉列表类型条件输入界面:

日期类型条件输入界面:

数字类型条件输入界面:

输入以上几种条件后,高级查询界面里面会显示友好的条件内容,确保用户能够看懂输入的条件,如下所示是输入几个不同类型的条件的显示内容。

日期类型和数字类型,为了方便,都可以单独输入其中的一部分作为条件进行高级查询。

为了方便,高级查询模块的内容,可以进行查询后在主界面列表中显示,也可以使用传统的查询按钮进行查询,使用传统查询按钮后,高级查询条件将失效,但是保留用户的输入,第二次打开界面后,会加载之前的输入条件,这样比较人性化一些,用户可以随时自由切换两种查询方式。

对于一些字段多的历史资料表,这种高级查询模式更加能够发挥其作用,用户可以在几十个甚至上百个字段中选择合适的条件,然后输入进行查询,这样能够使得客户更加有认同感,例如下面是一个病人历史档案资料表的高级查询界面,里面很多字段,使用这个扩展查询就是最合适不过了。

2、通用高级查询模块的实现思路

1)获取数据库字段名称和类型列表

首先前面说到,我是根据字段类型进行不同的控件显示并输入的,因此需要一个通用的函数获取字段的名称和类型,作为参考,由于这个功能比较通用,因此把它放在我的Winform开发框架的数据库基类的抽象类里面,所有的数据库访问类均继承不用重复写代码。

  1. /// <summary>
  2. /// 获取表的字段名称和数据类型列表。
  3. /// </summary>
  4. /// <returns></returns>
  5. public DataTable GetFieldTypeList()
  6. {
  7. DataTable dt = DataTableHelper.CreateTable("ColumnName,DataType");
  8. DataTable schemaTable = GetReaderSchema(tableName);
  9. if (schemaTable != null)
  10. {
  11. foreach (DataRow dr in schemaTable.Rows)
  12. {
  13. string columnName = dr["ColumnName"].ToString().ToUpper();
  14. string netType = dr["DataType"].ToString().ToLower();
  15.  
  16. DataRow row = dt.NewRow();
  17. row["ColumnName"] = columnName;
  18. row["DataType"] = netType;
  19.  
  20. dt.Rows.Add(row);
  21. }
  22. }
  23. return dt;
  24. }
  25.  
  26. /// <summary>
  27. /// 获取指定表的元数据,包括字段名称、类型等等
  28. /// </summary>
  29. /// <param name="tableName">数据库表名</param>
  30. /// <returns></returns>
  31. private DataTable GetReaderSchema(string tableName)
  32. {
  33. DataTable schemaTable = null;
  34.  
  35. string sql = string.Format("Select * FROM {0}", tableName);
  36. Database db = CreateDatabase();
  37. DbCommand command = db.GetSqlStringCommand(sql);
  38. try
  39. {
  40. using (IDataReader reader = db.ExecuteReader(command))
  41. {
  42. schemaTable = reader.GetSchemaTable();
  43. }
  44. }
  45. catch (Exception ex)
  46. {
  47. LogTextHelper.Error(ex);
  48. }
  49.  
  50. return schemaTable;
  51. }

2)设置高级查询的字段显示(有时候可能需要过滤部分字段)

3)指定下拉列表的数据内容

刚才说到,有一些下拉列表字段的输入,那么下拉列表也就需要指定里面的列表内容了,高级查询模块,指定下拉列表的代码如下所示。

  1.          dlg.AddColumnListItem("MidVideo", GetFieldListItem("MidVideo"));
  2. dlg.AddColumnListItem("InDiagnosis", GetFieldListItem("InDiagnosis"));
  3. dlg.AddColumnListItem("DirectorSurgeon", GetFieldListItem("DirectorSurgeon"));
  4. dlg.AddColumnListItem("TumorPart", GetFieldListItem("TumorPart"));
  5. dlg.AddColumnListItem("LeaveDiagnosis", GetFieldListItem("LeaveDiagnosis"));
  6. dlg.AddColumnListItem("IsFirstTime", GetFieldListItem("IsFirstTime"));
  7. dlg.AddColumnListItem("Professor", GetFieldListItem("Professor"));

对于一些固定的列表项目,我们也可以通过下面代码进行绑定。

  1. dlg.AddColumnListItem("Sex", new List<CListItem>() { new CListItem("男"), new CListItem("女") });
  2. dlg.AddColumnListItem("HasReferral", new List<CListItem>() { new CListItem("是"), new CListItem("否") });

4)和普通查询功能并存

为了使得传统查询按钮,和高级查询能够并存,我们需要存储一个高级查询的查询对象,但传统查询的时候,我们把高级查询对象设置为空即可屏蔽高级查询的条件了。

  1. /// <summary>
  2. /// 高级查询条件语句对象
  3. /// </summary>
  4. private SearchCondition advanceCondition;
  5.  
  6. /// <summary>
  7. /// 根据查询条件构造查询语句
  8. /// </summary>
  9. private string GetConditionSql()
  10. {
  11. //如果存在高级查询对象信息,则使用高级查询条件,否则使用主表条件查询
  12. SearchCondition condition = advanceCondition;
  13. if (condition == null)
  14. {
  15. condition = new SearchCondition();
  16. condition.AddCondition("BedNo", this.txtBedNo.Text.Trim(), SqlOperator.Like);
  17. condition.AddCondition("TumorPart", this.txtTumorPart.Text.Trim(), SqlOperator.Like);
  18. condition.AddCondition("MidVideo", this.txtMidVideo.Text.Trim(), SqlOperator.Like);
  19. condition.AddCondition("Name", this.txtName.Text.Trim(), SqlOperator.Like);
  20. condition.AddCondition("HospitalNo", this.txtHospitalNo.Text.Trim(), SqlOperator.Like);
  21. condition.AddCondition("IDNumber", this.txtIDNumber.Text.Trim(), SqlOperator.Like);
  22. condition.AddCondition("InDiagnosis", this.txtInDiagnosis.Text.Trim(), SqlOperator.Like);
  23. condition.AddCondition("LeaveDiagnosis", this.txtLeaveDiagnosis.Text.Trim(), SqlOperator.Like);
  24. condition.AddCondition("LeaveSpecimens", this.txtLeaveSpecimens.Text.Trim(), SqlOperator.Like);
  25. condition.AddCondition("Professor", this.txtProfessor.Text.Trim(), SqlOperator.Like);
  26. condition.AddCondition("Note", this.txtNote.Text.Trim(), SqlOperator.Like);
  27. condition.AddCondition("Pathology", this.txtPathology.Text.Trim(), SqlOperator.Like);
  28. condition.AddCondition("IsFirstTime", this.txtIsFirstTime.Text.Trim(), SqlOperator.Like);
  29. ..................
  30.  
  31. }
  32.  
  33. string where = condition.BuildConditionSql().Replace("Where", "");
  34.  
  35. return where;
  36. }
  1. /// <summary>
  2. /// 查询数据操作
  3. /// </summary>
  4. private void btnSearch_Click(object sender, EventArgs e)
  5. {
  6. advanceCondition = null;//必须重置查询条件,否则可能会使用高级查询条件了
  7. BindData();
  8. }

5)根据类型转换不同的窗体

为了输入方便,我定义了几个不同输入内容的窗体,然后根据不同的字段类型,构造不同的窗体并进行显示,这样比较合理显示并接收客户的条件输入。

  1. private void gridControl1_MouseDoubleClick(object sender, MouseEventArgs e)
  2. {
  3. int[] rowSelected = this.gridView1.GetSelectedRows();
  4. if (rowSelected.Length == ) return;
  5.  
  6. string fieldName = this.gridView1.GetFocusedRowCellValue("字段").ToString();
  7. string fieldDisplay = this.gridView1.GetFocusedRowCellValue("字段名称").ToString();
  8. FieldType fieldType = (FieldType)this.gridView1.GetFocusedRowCellValue("字段类型");
  9. string fieldValue = this.gridView1.GetFocusedRowCellValue("查询条件值").ToString();
  10. #region 根据类型转换不同的窗体
  11. FrmQueryBase dlg = null;
  12. if (fieldType == FieldType.Text)
  13. {
  14. dlg = new FrmQueryTextEdit();
  15. }
  16. else if (fieldType == FieldType.Numeric)
  17. {
  18. dlg = new FrmQueryNumericEdit();
  19. }
  20. else if (fieldType == FieldType.DateTime)
  21. {
  22. dlg = new FrmQueryDateEdit();
  23. }
  24. else if (fieldType == FieldType.DropdownList)
  25. {
  26. dlg = new FrmQueryDropdown();
  27. }
  28. #endregion

6)主窗体的事件响应

由于弹出的高级查询窗体,里面的查询以及清除操作,都是通过主窗体的事件进行处理,因此,弹出的高级查询窗体,只需要调用相应的事件即可。

  1. dlg.DataClear += new FrmQueryBase.DataClearEventHandler(dlg_DataClear);
  2. if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  3. {
  4. //更新查询界面显示
  5. UpdateFieldValue(fieldName, dlg.ReturnValue, dlg.ReturnDisplay);
  6.  
  7. //更新父窗体的数据显示
  8. ProcessDataSearch(null, null);
  9. }

这样我们就能把传统查询功能和高级查询功能合并一起,发挥最大的作用,是我们的程序能够尽量满足客户的需求,获得更加好的反馈和支持了。

Winform开发框架之通用高级查询模块的更多相关文章

  1. Winform开发框架之通用高级查询模块--SNF快速开发平台3.3-Spring.Net.Framework

    最近项目确实忙,但也是一直忙于有关项目和框架技术的事情,也一直致力于改善我的WInform开发框架.使得自己及客户使用起来更加方便,更加友好,更加高效. 在很多程序模块中都很常见,也是给客户扩展查询的 ...

  2. Winform开发框架之通用附件管理模块 --SNF快速开发平台3.3-Spring.Net.Framework

    最近项目太多都没有时间写文章了,实际项目需求一,CS端和windows平板都需要附件上传管理功能.以前做的都是BS的附件管理和上传功能.本来计划在Winform上嵌套一个浏览器直接用bs的附件上传功能 ...

  3. Winform开发框架之通用自动更新模块(转)

    在网络化的环境中,特别是基于互联网发布的Winform程序,程序的自动更新功能是比较重要的操作,这样可以避免挨个给使用者打电话.发信息通知或者发送软件等,要求其对应用程序进行升级.实现程序的自动更新, ...

  4. Winform开发框架之通用Windows摄像头调用拍照--SNF快速开发平台3.3-Spring.Net.Framework

    今天做了一个windows系统下调用摄像头.进行开启.关闭.拍照.设置等等功能演示. 进行源码贡献,欢迎大家下载使用 一.DEMO效果如下: 二.DEMO演示代码如下: using SNF.Utili ...

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

    1.通用数据导入导出操作模块回顾 在我的Winfrom开发框架里面,有一个通用的导入模块,它在默默处理这把规范的Excel数据导入到不同的对象表里面,一直用它来快速完成数据导入的工作.很早在随笔< ...

  6. ABP开发框架前后端开发系列---(13)高级查询功能及界面的处理

    在一般的检索界面中,基于界面易用和美观方便的考虑,我们往往只提供一些常用的条件查询进行列表数据的查询,但是有时候一些业务表字段很多,一些不常见的条件可能在某些场景下也需要用到.因此我们在通用的查询条件 ...

  7. Winform开发框架之统计图表的实现

    在前面的一些随笔中,介绍了不少我的Winform框架的特性,上篇随笔<Winform开发框架之通用高级查询模块>对其中的通用高级模块进了一个整理说明,本篇继续介绍Winform开发框架重要 ...

  8. [转载]Winform开发框架之统计图表的实现

    在前面的一些随笔中,介绍了不少我的Winform框架的特性,上篇随笔<Winform开发框架之通用高级查询模块>对其中的通用高级模块进了一个整理说明,本篇继续介绍Winform开发框架重要 ...

  9. Winform开发框架之图表报表在线设计器2-图表-SNF.EasyQuery项目--SNF快速开发平台3.3-Spring.Net.Framework

    上一篇讲到,如何快速创建报表程序了.这篇教大家如何快速制作图表报表. 继上一篇,Winform开发框架之图表报表在线设计器-报表 上一篇讲到如何了创建数据源,这里就不在介绍了.那我们就直接从图表设计器 ...

随机推荐

  1. 移动应用安全开发指南(Android)--完结篇(http://www.bubuko.com/infodetail-577312.html)

    1.认证和授权 概述 认证是用来证明用户身份合法性的过程,授权是用来证明用户可以合法地做哪些事的过程,这两个过程一般是在服务器端执行的,但也有的APP出于性能提升或用户体验等原因,将其做在客户端完成, ...

  2. android自定义viewgroup之我也玩瀑布流

    先看效果图吧, 继上一篇<android自定义viewgroup实现等分格子布局>中实现的布局效果,这里稍微有些区别,每个格子的高度不规则,就是传说的瀑布流布局,一般实现这种效果,要么用第 ...

  3. Spring Boot 之 RESRful API 权限控制

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “简单,踏实~ 读书写字放屁” 一.为何用RESTful API 1.1 RESTful是什么? ...

  4. 专访Linux嵌入式开发韦东山操作系统图书作者--转

    CSDN学院讲师韦东山:悦己之作,方能悦人 发表于2015-04-28 08:09| 6669次阅读| 来源CSDN| 24 条评论| 作者夏梦竹 专访Linux嵌入式开发韦东山操作系统图书作者 摘要 ...

  5. preg_match_all正则表达式的基本使用

    了解正则表达式之前,须要掌握一些常用的正则表达式的基础知识,这些如果能记得最好记得,记不住须要用的时候能查到就行,就多个特殊字符,所以说正则表达式玩的就是特殊,具体大家可以查看更加细致的说明. pre ...

  6. Ubuntu下的杀毒

      Ubuntu 11.04 杀毒软件ESET NOD32   Linux防病毒,并不代表没有病毒,只是数量过少.因技术精英发现漏洞后即时打补丁,病毒很少. 有兴趣的同学可以尝试下Ubuntu 11. ...

  7. Session丢失的解决办法小结

    最近在做ASP.NET项目时,测试网站老是取不出Session中的值,在网上搜索了一下,找到一些解决方法,记录在这里.最后使用存储在StateServer中的办法解决了问题. SessionState ...

  8. MYSQL开发性能研究——批量插入的优化措施

    一.我们遇到了什么问题 在标准SQL里面,我们通常会写下如下的SQL insert语句. INSERT INTO TBL_TEST (id) VALUES(1);   很显然,在MYSQL中,这样的方 ...

  9. 跨域名 Cookie 传递测试

    问题 我打开了 www.aaa.com 里面的一个页面(www.aaa.com/hello.php),其中这个 hello.php 里面包含一个 <img> 标签,里面的 src 来自于 ...

  10. JS 获取一个对象里面第一层元素的数量

    function getObjectLength(obj) { var i = 0; for(var k in obj){ i++; } return i; } var obj = { a: 1, b ...