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

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

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

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

通用界面与基本的流程

通用的界面

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

基本的流程

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

基类的基本实现

构造函数

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);
    }
}
posted @ 2015-09-08 09:56  马非码  阅读(4302)  评论(3编辑  收藏  举报