参考博客下方:http://www.cnblogs.com/wuhuacong/archive/2010/05/31/1748579.html

对于一般常用到的编辑数据、新增数据窗体,分开了两个不同的窗体进行处理,而且由于BaseForm窗体没有对通用的函数进行进一步的抽象,因此,编辑及新增窗体多了很多重复累赘的代码,其实可以把新增、编辑合并一个窗体,然后根据新增、编辑两种不同的条件进行处理即可。

由于BaseForm一般需要在大多数的窗体中,而新增编辑数据窗体一般较为特殊一点,可以再增加一个基类BaseEditForm,用来做新增编辑窗体的基类,该基类继承自BaseForm类,工程代码如下所示。

其中运行例子的效果如下所示:

编辑以及新增我们整合在一个窗体中,先看看该基类的设计视图,我们在其中添加了3个按钮(常用的添加、保存、关闭按钮)。

窗体的代码我大类采用了可重载的虚函数,留给子类窗体进行实现不同的处理操作,如窗体加载显示操作、显示数据到控件的操作、保存、新增等函数都是需要实现的,而调用逻辑以及一些通用的处理,则在基类BaseEditForm中实现,子类不用重复这些代码,按钮控件(添加、保存、关闭)的事件处理也已经进行了逻辑封装,如下所示。

代码

  1.  
  2.         public override void FormOnLoad()
  3.         {
  4.             base.FormOnLoad();
  5.             if (!this.DesignMode)
  6.             {
  7.                 if (!string.IsNullOrEmpty(ID))
  8.                 {
  9.                     this.Text = "编辑 " + this.Text;
  10.                     this.btnAdd.Visible = false;//如果是编辑,则屏蔽添加按钮
  11.                 }
  12.                 else
  13.                 {
  14.                     this.Text = "新建 " + this.Text;
  15.                 }
  16.                 
  17.                 DisplayData();
  18.             }
  19.         }
  20.  
  21.        /// <summary>
  22.         /// 显示数据到控件上
  23.         /// </summary>
  24.         public virtual void DisplayData()
  25.         {
  26.         } 
  27.         
  28.         /// <summary>
  29.         /// 检查输入的有效性
  30.         /// </summary>
  31.         /// <returns>有效</returns>
  32.         public virtual bool CheckInput()
  33.         {
  34.             return true;
  35.         }
  36.                
  37.         /// <summary>
  38.         /// 清除屏幕
  39.         /// </summary>
  40.         public virtual void ClearScreen()
  41.         {
  42.             this.ID = "";////需要设置为空,表示新增
  43.             ClearControlValue(this);
  44.             this.FormOnLoad();
  45.         }
  46.        
  47.         /// <summary>
  48.         /// 保存数据(新增和编辑的保存)
  49.         /// </summary>
  50.         public virtual bool SaveEntity()
  51.         {
  52.             bool result = false;
  53.             if(!string.IsNullOrEmpty(ID))
  54.             {
  55.                 //编辑的保存
  56.                 result = SaveUpdated();
  57.             }
  58.             else
  59.             {
  60.                 //新增的保存
  61.                 result = SaveAddNew();
  62.             }
  63.  
  64.             return result;
  65.         }
  66.  
  67.         /// <summary>
  68.         /// 更新已有的数据
  69.         /// </summary>
  70.         /// <returns></returns>
  71.         public virtual bool SaveUpdated()
  72.         {
  73.             return true;
  74.         }
  75.  
  76.         /// <summary>
  77.         /// 保存新增的数据
  78.         /// </summary>
  79.         /// <returns></returns>
  80.         public virtual bool SaveAddNew()
  81.         {
  82.             return true;
  83.         }
  84.  
  85.         /// <summary>
  86.         /// 保存
  87.         /// </summary>
  88.         /// <param name="close">关闭窗体</param>
  89.         private void SaveEntity(bool close)
  90.         {
  91.             // 检查输入的有效性
  92.             if (this.CheckInput())
  93.             {
  94.                 // 设置鼠标繁忙状态
  95.                 this.Cursor = Cursors.WaitCursor;
  96.                 try
  97.                 {
  98.                     if (this.SaveEntity())
  99.                     {
  100.                         MessageUtil.ShowTips("保存成功");
  101.                         if (close)
  102.                         {
  103.                             this.DialogResult = DialogResult.OK;
  104.                             this.Close();
  105.                         }
  106.                         else
  107.                         {
  108.                             this.ClearScreen();
  109.                         }                           
  110.                     }
  111.                 }
  112.                 catch (Exception ex)
  113.                 {
  114.                     this.ProcessException(ex);
  115.                 }
  116.                 finally
  117.                 {
  118.                     // 设置鼠标默认状态
  119.                     this.Cursor = Cursors.Default;
  120.                 }
  121.             }
  122.         }
  123.  
  124.         private void btnAdd_Click(object sender, EventArgs e)
  125.         {
  126.             this.SaveEntity(false);
  127.         }
  128.  
  129.         private void btnOK_Click(object sender, EventArgs e)
  130.         {
  131.             this.SaveEntity(true);
  132.         }
  133.  
  134.         private void btnCancel_Click(object sender, EventArgs e)
  135.         {
  136.             this.DialogResult = DialogResult.Cancel;
  137.             this.Close();
  138.         }
  139.  

其中值得介绍的是,窗体的控件数据清空在基类窗体中通过遍历实现了通用的数据清空操作,该部分代码引用了“潇湘隐者的博客(http://www.cnblogs.com/kerrycode/archive/2010/02/05/1664267.html),对此感谢。

另外,基类窗体还实现了Tab键的转换,这个思路来源于即日嘎拉的代码,但由于是基类实现,有些不同,他的放在每个具体的子类中,因此通用性有些限制。

我们重载了ProcessCmdKey(ref Message msg, Keys keyData) 函数后,就可以实现统一的回车键转换了。

  1.  
  2. 代码
  3.         protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
  4.         {       
  5.             if (keyData == Keys.F5)
  6.             {
  7.                 this.FormOnLoad();
  8.             }
  9.  
  10.             if ((!(ActiveControl is Button)) &&
  11.                 (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Enter))
  12.             {
  13.                 if (keyData == Keys.Enter)
  14.                 {
  15.                     System.Windows.Forms.SendKeys.Send("{TAB}");
  16.                     return true;
  17.                 }
  18.                 if (keyData == Keys.Down)
  19.                 {
  20.                     System.Windows.Forms.SendKeys.Send("{TAB}");
  21.                 }
  22.                 else
  23.                 {
  24.                     SendKeys.Send("+{Tab}");
  25.                 }
  26.  
  27.                 return true;
  28.             }
  29.             else
  30.             {
  31.                 return base.ProcessCmdKey(ref msg, keyData);
  32.             }
  33.         }

最后,我们看看具体的子类窗体,看新增编辑界面需要实现的代码,如下所示,其中大部分是原子级别的操作,逻辑操作已经在基类中实现了哦:

代码

  1.  
  2.     public partial class FrmEditCustomer : BaseUI.BaseEditForm
  3.     {
  4.         public FrmEditCustomer()
  5.         {
  6.             InitializeComponent();
  7.         }
  8.  
  9.         /// <summary>
  10.         /// 实现控件输入检查的函数
  11.         /// </summary>
  12.         /// <returns></returns>
  13.         public override bool CheckInput()
  14.         {
  15.             bool result = true;
  16.  
  17.             #region 输入验证
  18.             if (this.txtName.Text.Length == 0)
  19.             {
  20.                 MessageUtil.ShowTips("宾客名称不能为空");
  21.                 this.txtName.Focus();
  22.                 result = false;
  23.             }
  24.             else if (this.txtIDNumber.Text.Length == 0)
  25.             {
  26.                 MessageUtil.ShowTips("证件号码不能为空");
  27.                 this.txtIDNumber.Focus();
  28.                 result = false;
  29.             }
  30.  
  31.             #endregion
  32.  
  33.             return result;
  34.         }
  35.  
  36.         /// <summary>
  37.         /// 编辑或者保存状态下取值函数
  38.         /// </summary>
  39.         /// <param name="info"></param>
  40.         private void SetInfo(CustomerInfo info)
  41.         {
  42.             info.Address = txtAddress.Text;
  43.             info.CompanyName = txtCompany.Text;
  44.             info.IDCarType = cmbIDCarType.Text;
  45.             info.Name = txtName.Text;
  46.             info.Note = txtNote.Text;
  47.             info.IDNumber = txtIDNumber.Text;
  48.             info.Telephone = txtTelephone.Text;
  49.             info.Source = cmbSource.Text;
  50.             info.CustomerType = cmbType.Text;
  51.             info.Sex = cmbSex.Text;
  52.         }
  53.  
  54.         /// <summary>
  55.         /// 数据字典加载
  56.         /// </summary>
  57.         private void InitDictItem()
  58.         {
  59.             this.cmbSource.Items.Clear();
  60.             this.cmbSource.Items.AddRange(DictItemUtil.GetCustomerSource());
  61.  
  62.             this.cmbType.Items.Clear();
  63.             this.cmbType.Items.AddRange(DictItemUtil.GetCustomerType());
  64.  
  65.             this.cmbIDCarType.Items.Clear();
  66.             this.cmbIDCarType.Items.AddRange(DictItemUtil.GetIDCarType());
  67.         }
  68.  
  69.         /// <summary>
  70.         /// 数据显示的函数
  71.         /// </summary>
  72.         public override void DisplayData()
  73.         {
  74.             //数据字典加载(公用)
  75.             InitDictItem();
  76.  
  77.             if (!string.IsNullOrEmpty(ID))
  78.             {
  79.                 //编辑状态下的数据显示
  80.                 CustomerInfo info = BLLFactory<Customer>.Instance.FindByID(ID);
  81.                 if (info != null)
  82.                 {
  83.                     #region 显示客户信息
  84.                     txtAddress.Text = info.Address;
  85.                     txtCompany.Text = info.CompanyName;
  86.                     txtName.Text = info.Name;
  87.                     txtNote.Text = info.Note;
  88.                     txtIDNumber.Text = info.IDNumber;
  89.                     txtTelephone.Text = info.Telephone;
  90.                     cmbSource.Text = info.Source;
  91.                     cmbType.Text = info.CustomerType;
  92.                     cmbSex.Text = info.Sex;
  93.                     cmbIDCarType.Text = info.IDCarType;
  94.                     lblCreateDate.Text = info.RegistrationDate.ToString();
  95.  
  96.                     #endregion
  97.                 }
  98.             }
  99.             else
  100.             {
  101.                 //新增状态的数据显示
  102.                 lblCreateDate.Text = DateTime.Now.ToString();
  103.             }
  104.         }
  105.  
  106.         /// <summary>
  107.         /// 新增状态下的数据保存
  108.         /// </summary>
  109.         /// <returns></returns>
  110.         public override bool SaveAddNew()
  111.         {
  112.             CustomerInfo info = new CustomerInfo();
  113.             SetInfo(info);
  114.             info.RegistrationDate = DateTime.Now;
  115.             bool succeed = BLLFactory<Customer>.Instance.Insert(info);
  116.             return succeed;
  117.         }
  118.  
  119.         /// <summary>
  120.         /// 编辑状态下的数据保存
  121.         /// </summary>
  122.         /// <returns></returns>
  123.         public override bool SaveUpdated()
  124.         {
  125.             CustomerInfo info = BLLFactory<Customer>.Instance.FindByID(ID);
  126.             if (info != null)
  127.             {
  128.                 SetInfo(info);
  129.                 bool succeed = BLLFactory<Customer>.Instance.Update(info, info.ID.ToString());
  130.                 return succeed;
  131.             }
  132.             return false;
  133.         }
  134.     }

winform 窗体实现增删改查(CRUD)窗体基类模式的更多相关文章

  1. winform 窗体实现增删改查(CRUD)共用模式

    转载:http://www.csframework.com/archive/2/arc-2-20110617-1632.htm 高度封装的编辑窗体 http://www.cnblogs.com/wuh ...

  2. IDEA SpringBoot-Mybatis-plus 实现增删改查(CRUD)

    上一篇: IDEA SpringBoot-Mybatis实现增删改查(CRUD) 下一篇:Intellij IDEA 高效使用教程 (插件,实用技巧) 最好用的idea插件大全 一.前言 Mybati ...

  3. 基于SSM之Mybatis接口实现增删改查(CRUD)功能

    国庆已过,要安心的学习了. SSM框架以前做过基本的了解,相比于ssh它更为优秀. 现基于JAVA应用程序用Mybatis接口简单的实现CRUD功能: 基本结构: (PS:其实这个就是用的Mapper ...

  4. C#使用Xamarin开发可移植移动应用进阶篇(10.综合演练,来一份增删改查CRUD)

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 呃 也有半 ...

  5. java中增删改查(CRUD)总结

    对于User表增删改查:1:save(保存方法)  view(查询所有记录) update(更新方法) delete(删除方法) 通过method这个参数进行判断执行不同的操作 2: 具体的实现:   ...

  6. idea+spring4+springmvc+mybatis+maven实现简单增删改查CRUD

    在学习spring4+springmvc+mybatis的ssm框架,idea整合简单实现增删改查功能,在这里记录一下. 原文在这里:https://my.oschina.net/finchxu/bl ...

  7. ssm 框架实现增删改查CRUD操作(Spring + SpringMVC + Mybatis 实现增删改查)

    ssm 框架实现增删改查 SpringBoot 项目整合 一.项目准备 1.1 ssm 框架环境搭建 1.2 项目结构图如下 1.3 数据表结构图如下 1.4 运行结果 二.项目实现 1. Emplo ...

  8. Winform 学生管理系统增删改查

    数据库: create database adonet go use adonet go create table xue ( code ), name ), sex bit, birth datet ...

  9. JDBC工具类 访问数据库 增删改查CRUD的通用方法

    1 package com.zmh.util; 2 3 import java.sql.*; 4 import java.util.ArrayList; 5 import java.util.Hash ...

随机推荐

  1. MDIO/MDC(SMI)接口-leonwang202

    ChinaUnix博客 http://blog.chinaunix.net/uid-24148050-id-132863.html

  2. webstorm es6 语法报错

    设置settings javascript language version后 <script>标签加个 type <script type="text/ecmascrip ...

  3. poj 2312 Battle City(优先队列+bfs)

    题目链接:http://poj.org/problem?id=2312 题目大意:给出一个n*m的矩阵,其中Y是起点,T是终点,B和E可以走,S和R不可以走,要注意的是走B需要2分钟,走E需要一分钟. ...

  4. 关于gsl库出现access violation 0X00000005问题的解决方法

    gsl即GNU SCIENCE LIBRARY是一个强大c/c++的数值计算函数库. 在使用这一库出现access violation 0X00000005问题,尝试方法一在project->C ...

  5. wxpython SizerItem的大小控制

    wxpython SizerItem的大小控制 proportion控制控件相对大小,proportion如果为0,表示默认大小.比如一个box里面有两个相同控件A,B,如果A,B的proportio ...

  6. [Leetcode Week4]H-Index

    H-Index题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/h-index/description/ Description Given an arr ...

  7. Linux下的Backlight子系统(二)【转】

    转自:http://blog.csdn.net/weiqing1981127/article/details/8515847 版权所有,转载必须说明转自 http://my.csdn.net/weiq ...

  8. Perl的Expect模块学习

    Perl的Expect模块学习 http://www.xuebuyuan.com/1852717.html

  9. 推荐下载App,如果本地安装则直接打开本地App(Android/IOS)

    推荐下载App,如果本地安装则直接打开本地App(Android/IOS) - 纵观现在每家移动网站,打开首页的时候,都有各种各样的形式来提示你下载自身的移动App(Android/IOS),这是做移 ...

  10. JSONObject依赖包

    commons-lang.jar commons-beanutils.jar commons-collections.jar commons-logging.jar ezmorph.jar json- ...