zoukankan      html  css  js  c++  java
  • 如何设计一个编辑窗体的基类

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

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

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

    通用界面与基本的流程

    通用的界面

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

    基本的流程

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

    基类的基本实现

    构造函数

    public EditFormBase()
    {
        ModelBound = false;
        _skipDefaultProcessCmdKey = false;
        AutoRename = true;
    
        InitializeComponent();
        Activated += EditFormBase_Activated;
        StartPosition = FormStartPosition.CenterScreen;
    }
    
    public EditFormBase(IListFormBase listFrm)
        : this()
    {
        ListForm = listFrm;
    }
    

    其要点如下:

    • ModelBound:在窗体编辑时有效,指示是否加载了数据库中的Model,因为很多时候,我们的控件是有相关联动而产生另外的数据的,有时候在数据绑定的时候并不想要产生这些事件,这个时候这个属性就非常有用。比如收款金额,可能是体积单价 * 体积,但是也可能是录单人员手动输入的,这个时候,我们保存的内容包括:体积单价、体积、收款金额;而编辑的时候,这个自动计算的功能是不需要的。
    • _skipDefaultProcessCmdKey:是否忽略现有的键盘按键的操作。基类中我重写了键盘按键事件,按ESC关闭窗体,按Enter提交表单。
    • AutoRename:是否允许基类自动对窗体进行命名。假设实现类中的Title写为“发货单”,那么,新增时基类自动命名为“新增发货单”;编辑时自动命名为“编辑发货单”。
    • EditFormBase_Activated:在这个事件中才处理Model的绑定,这样可以确保Model的绑定在Form_Load事件之后。
    • IListFormBase listFrm:列表界面接口。这个接口要求列表界面对列表数据进行刷新,这样,我们在编辑和更新时候,就可以同时更新列表的数据了。因此,列表窗体必须实现这个接口。

    窗体加载与激活

    ///窗体加载
    private void EditFormBase_Load(object sender, EventArgs e)
    {
        if (IsEdit)
        {
            if (AutoRename)
                Text = "编辑" + Text;
        }
        else
        {
            ModelBound = true;
            if (AutoRename)
                Text = "添加" + Text;
        }
    }
    ///窗体激活
    private void EditFormBase_Activated(object sender, EventArgs e)
    {
        if (!FormLoaded)
        {
            if (IsEdit)
            {
                BindEntity();
                ModelBound = true;
                AfterBindEntity();
            }
            FormLoaded = true;
        }
    }
    

    提交表单

    //提交操作,一般在点击按钮之后触发
    protected void ReadySaveEntity(bool close)
    {
        if (CheckInput())
        {
            Cursor = Cursors.WaitCursor;
            string operation = IsEdit ? "编辑" : "添加";
            try
            {
                if (SaveOrUpdateEntity(IsEdit))
                {
                    MessageBoxHelper.ShowTipsSlide("{0}成功!!!", operation);
                    RefreshUi();
                    if (close)
                    {
                        DialogResult = DialogResult.OK;
                        Close();
                    }
                    else
                    {
                        ClearScreen();
                    }
                }
            }
            catch (Exception ex)
            {
                OnSaveOrUpdateError(ex, operation);
            }
            finally
            {
                Cursor = Cursors.Default;
            }
        }
    }
    
    //实际的提交,是一个虚方法,需要子类实现,没有实现将会弹出警告框
    protected virtual bool SaveOrUpdateEntity(bool isEdit)
    {
        MessageBoxHelper.ShowTips("没有实现添加或者编辑记录的接口,请与开发人员联系");
        return false;
    }
    

    列表更新与界面清空

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

    数据绑定、控件验证

    //都是空方法,需要子类实现
    protected virtual void BindEntity()
    {
    }
    
    protected virtual void AfterBindEntity()
    {
    
    }
    

    使用实例

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

    其基本实现步骤如下:

    继承基类

    public partial class SendOrderEdit : EditFormBase
    {
    	public SendOrderEdit(IListFormBase list)
            : base(list)
        {
            InitializeComponent();
    	}
    }
    

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

    //保存并新增
    private void btnSaveAndAdd_Click(object sender, EventArgs e)
    {
        ReadySaveEntity(false);
        IsEdit = false;
    }
    //保存并关闭
    private void btnSaveAndClose_Click(object sender, EventArgs e)
    {
        ReadySaveEntity(true);
    }
    

    实现基本的操作流程

    • 验证CheckInput
    • 数据绑定BindEntity
    • 提交数据库SaveOrUpdateEntity
    • 清空界面ClearScreen
    • 如果需要控制刷新列表的参数,需要重写刷新方法RefreshUi

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

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

    它的实现非常简单:

    public partial class BaseFormEditNew : EditFormBase
    {
        public BaseFormEditNew()
        {
            InitializeComponent();
        }
    
        public BaseFormEditNew(IListFormBase list)
            : base(list)
        {
            InitializeComponent();
        }
    
        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }
    
        private void btnSave_Click(object sender, EventArgs e)
        {
            ReadySaveEntity(true);
        }
    }
  • 相关阅读:
    L3-028 森森旅游 题解(最短路)
    Codeforces Round #717 (Div. 2) 题解(A-D)
    大爽Python入门教程 总目录
    Django笔记&教程 2-4 视图常用
    python一对一教程:Computational Problems for Physics chapter 1-B Code Listings 1.7
    python一对一教程:Computational Problems for Physics chapter 1 Code Listings
    b站个人直播年报【大爽歌作】 介绍与演示
    架构漫谈阅读笔记03
    架构漫谈阅读笔记02
    架构漫谈阅读笔记01
  • 原文地址:https://www.cnblogs.com/marvin/p/EditFormBase.html
Copyright © 2011-2022 走看看