如何设计一个编辑窗体的基类

开发
我们发现对于编辑窗体而言,它们的工作基本的流程是大同小异,而且编辑窗体中每次都需要增加按键处理、是否有编辑内容未保存等提示,因此我们需要一个基类来把这些基本的事情完成。

为什么我们需要一个编辑的基类呢?

我们发现对于编辑窗体而言,它们的工作基本的流程是大同小异,而且编辑窗体中每次都需要增加按键处理、是否有编辑内容未保存等提示,因此我们需要一个基类来把这些基本的事情完成。

下面,我们看看是如何实现这个基类的。

通用界面与基本的流程

通用的界面

我们的编辑界面通常是在一个列表界面中,通过点击添加或者编辑按钮,打开一个编辑窗体,他们通常长成下面的这个样子:

基本的流程

我们总结一下基本的流程是下面这样的:

基类的基本实现

构造函数

 

  1. public EditFormBase(){    ModelBound = false;    _skipDefaultProcessCmdKey = false;    AutoRename = true
  2.     InitializeComponent();    Activated += EditFormBase_Activated;    StartPosition = FormStartPosition.CenterScreen;} 
  3. public EditFormBase(IListFormBase listFrm)    : this(){    ListForm = listFrm;} 
  4.  
  5. 其要点如下: 
  • ModelBound:在窗体编辑时有效,知识是否加载了数据库中的Model,因为很多时候,我们的控件是有相关联动而产生另外的数据的,有时候在数据绑定的时候并不想要产生这些事件,这个时候这个属性就非常有用。比如收款金额,可能是**体积单价*体积**,但是也可能是录单人员手动输入的,这个时候,我们保存的内容包括:体积单价、体积、收款金额;而编辑的时候,这个自动计算的功能是不需要的。

  • _skipDefaultProcessCmdKey:是否忽略现有的键盘按键的操作。基类中我重写了键盘按键事件,按ESC关闭窗体,按Enter提交表单。

  • AutoRename:是否允许基类自动对窗体进行命名。假设实现类中的Title写为“发货单”,那么,新增时基类自动命名为“新增发货单”;编辑时自动命名为“编辑发货单”。

  • EditFormBase_Activated:在这个事件中才处理Model的绑定,这样可以确保Model的绑定在Form_Load事件之后。

  • IListFormBase listFrm:列表界面接口。这个接口要求列表界面对列表数据进行刷新,这样,我们在编辑和更新时候,就可以同时更新列表的数据了。因此,列表窗体必须实现这个接口。

窗体加载与激活

  1. ///窗体加载 
  2. private void EditFormBase_Load(object sender, EventArgs e) 
  3.     if (IsEdit) 
  4.     { 
  5.         if (AutoRename) 
  6.             Text = "编辑" + Text; 
  7.     } 
  8.     else 
  9.     { 
  10.         ModelBound = true
  11.         if (AutoRename) 
  12.             Text = "添加" + Text; 
  13.     } 
  14. ///窗体激活 
  15. private void EditFormBase_Activated(object sender, EventArgs e) 
  16.     if (!FormLoaded) 
  17.     { 
  18.         if (IsEdit) 
  19.         { 
  20.             BindEntity(); 
  21.             ModelBound = true
  22.             AfterBindEntity(); 
  23.         } 
  24.         FormLoaded = true
  25.     } 

提交表单

  1. //提交操作,一般在点击按钮之后触发 
  2. protected void ReadySaveEntity(bool close) 
  3.     if (CheckInput()) 
  4.     { 
  5.         Cursor = Cursors.WaitCursor; 
  6.         string operation = IsEdit ? "编辑" : "添加"
  7.         try 
  8.         { 
  9.             if (SaveOrUpdateEntity(IsEdit)) 
  10.             { 
  11.                 MessageBoxHelper.ShowTipsSlide("{0}成功!!!", operation); 
  12.                 RefreshUi(); 
  13.                 if (close) 
  14.                 { 
  15.                     DialogResult = DialogResult.OK; 
  16.                     Close(); 
  17.                 } 
  18.                 else 
  19.                 { 
  20.                     ClearScreen(); 
  21.                 } 
  22.             } 
  23.         } 
  24.         catch (Exception ex) 
  25.         { 
  26.             OnSaveOrUpdateError(ex, operation); 
  27.         } 
  28.         finally 
  29.         { 
  30.             Cursor = Cursors.Default; 
  31.         } 
  32.     } 
  33.  
  34. //实际的提交,是一个虚方法,需要子类实现,没有实现将会弹出警告框 
  35. protected virtual bool SaveOrUpdateEntity(bool isEdit) 
  36.     MessageBoxHelper.ShowTips("没有实现添加或者编辑记录的接口,请与开发人员联系"); 
  37.     return false

列表更新与界面清空

  1. //都是有默认的实现,当然你可以可以自己重写 
  2. protected virtual void RefreshUi() 
  3.     if (ListForm != null
  4.     { 
  5.         ListForm.RefreshListView(""); 
  6.     } 
  7.     else 
  8.     { 
  9.         MessageBoxHelper.ShowTips("没有实现刷新界面的接口,请与开发人员联系"); 
  10.     } 

数据绑定、控件验证

  1. //都是空方法,需要子类实现 
  2. protected virtual void BindEntity() 
  3.  
  4. protected virtual void AfterBindEntity() 
  5.  

使用实例

以下面的界面为例子,我们讲讲如何实现这个编辑窗体

其基本实现步骤如下:

继承基类

 

  1. public partial class SendOrderEdit : EditFormBase 
  2. public SendOrderEdit(IListFormBase list) 
  3. : base(list) 
  4. InitializeComponent(); 

 

触发保存并新增、保存并关闭按钮

  1. //保存并新增 
  2. private void btnSaveAndAdd_Click(object sender, EventArgs e) 
  3.     ReadySaveEntity(false); 
  4.     IsEdit = false
  5. //保存并关闭 
  6. private void btnSaveAndClose_Click(object sender, EventArgs e) 
  7.     ReadySaveEntity(true); 

实现基本的操作流程

  • 验证CheckInput

  • 数据绑定BindEntity

  • 提交数据库SaveOrUpdateEntity

  • 清空界面ClearScreen

  • 如果需要控制刷新列表的参数,需要重写刷新方法RefreshUi

带保存按钮和关闭按钮的基类

为了更简化我们的操作和统一编辑界面,我们同时提供了下面这个编辑窗体基类,是带有保存按钮和关闭按钮的:

它的实现非常简单:

 

  1. public partial class BaseFormEditNew : EditFormBase 
  2.     public BaseFormEditNew() 
  3.     { 
  4.         InitializeComponent(); 
  5.     } 
  6.  
  7.     public BaseFormEditNew(IListFormBase list) 
  8.         : base(list) 
  9.     { 
  10.         InitializeComponent(); 
  11.     } 
  12.  
  13.     private void btnCancel_Click(object sender, EventArgs e) 
  14.     { 
  15.         Close(); 
  16.     } 
  17.  
  18.     private void btnSave_Click(object sender, EventArgs e) 
  19.     { 
  20.         ReadySaveEntity(true); 
  21.     } 
责任编辑:王雪燕 来源: 博客园
相关推荐

2021-05-28 18:12:51

C++设计

2009-07-24 11:29:33

WinForm表单窗体

2013-07-01 11:01:22

API设计API

2020-03-26 09:36:06

AB Test平台的流量

2018-09-18 09:38:11

RPC远程调用网络通信

2024-11-20 13:18:21

2020-09-22 07:50:23

API接口业务

2024-04-24 10:38:22

2010-02-23 15:52:14

Python编辑器

2020-09-02 07:22:17

JavaScript插件框架

2022-09-13 08:01:58

短链服务哈希算法字符串

2023-09-08 08:10:48

2020-11-11 09:49:12

计算架构

2023-09-08 08:22:30

2024-08-27 12:49:20

2011-03-03 10:03:19

2011-09-10 19:47:58

维基泄密安全策略数据安全

2021-05-20 13:22:31

架构运维技术

2012-11-20 09:33:02

2019-11-20 23:44:29

接口数据加密数据安全
点赞
收藏

51CTO技术栈公众号