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);
        }
    }
  • 相关阅读:
    Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点
    Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
    Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线
    Civil 3D 二次开发 新建CLR项目出现错误C2143
    Civil 3D 二次开发 创建AutoCAD对象—— 00 ——
    了解AutoCAD对象层次结构 —— 6 ——块表记录
    datepicker97使用
    使用angular 外接 templateUrl,使用ng-include
    angularJs 遮罩
    网上找的有关css兼容问题
  • 原文地址:https://www.cnblogs.com/marvin/p/EditFormBase.html
Copyright © 2011-2022 走看看