在我的隨筆中,Winform開發介紹過很多內容,隨著介紹的深入,很多地方進行精細化的介紹當中了。我們一般在Winform的列表界面中展現相關記錄,在一個彈出窗口給客戶錄入數據,OK,這些沒問題,但是我們錄入數據後,很多情況下忽略了一些用戶體驗,等客戶自己刷新才在列表中顯示最新的記錄出來,這樣有些注重細節的客戶就不願意了。在我的一個項目開發中,有客戶就有這樣的抱怨,為什麼我錄入數據,還要手動刷新,為什麼不能一保存就能同時更新列表?好,技術上肯定不是問題,思想考慮不夠深入而已。下面我來介紹基於我的Winform開發框架的這種數據即時更新的實現過程。
在開篇之前,首先介紹一下Winform開發框架中的界面層的繼承關系,首先我把所有窗體區分為三類,一類是普通的窗體,一類編輯窗體,還有一類是列表顯示窗體。窗體的集成可以封裝處理很多東西,良好的封裝和繼承,可以為我們提高效率,減少重復代碼,它的作用不再在此討論和強調。
采用窗體繼承,極大程度上統一了界面,並且對常用的界面操作,提供了良好的封裝,如基礎數據編輯、新增窗體積累封裝了對回車、方向鍵、數據刷新、異常處理、數據檢查、數據保存、數據更新等接口,為窗體的數據處理提供了很大的方便性。
而數據查詢顯示窗體則考慮到多文檔展示的需要,一般繼承合適的基類,封裝一些常用到的界面布局,以便實現相應的界面處理效果。
上面所述的三類窗體,繼承的界面基類分別是下面幾個。普通的窗體繼承自BaseForm,編輯窗體繼承自BaseEditForm,列表顯示窗體繼承自BaseDock。在工程中如下所示。
在UML設計圖中,我們看到他的關系如下所示,其中綠色邊框的為我們上面的基類,紅色邊框的是我們實際的窗體對象,從這個圖中,我們可以很清晰看到他的關聯關系。
BaseEditForm相對來說,比其他兩個基類窗體復雜一些,他除了提供幾個數據保存必須的按鈕外,還可以通過前後進行數據查看,他的初始化界面及應用例子界面如下所示。
介紹完上面的繼承關系後,我們來看看基於這種繼承模式,如何實現數據及時更新的操作,也就是在數據保存窗體,保存數據後,數據記錄同步在列表中展現的效果。
1)首先在基類界面BaseEditForm中添加事件處理
public partial class BaseEditForm : BaseForm
{
public event EventHandler OnDataSaved;//子窗體數據保存的觸發
2)然後添加事件的處理操作,如下所示。
/// <summary>
/// 處理數據保存後的事件觸發
/// </summary>
public virtual void ProcessDataSaved(object sender, EventArgs e)
{
if (OnDataSaved != null)
{
OnDataSaved(sender, e);
}
}
3)在數據保存的時候,觸發即時更新數據的事件
/// <summary>
/// 保存數據(新增和編輯的保存)
/// </summary>
public virtual bool SaveEntity()
{
bool result = false;
if(!string.IsNullOrEmpty(ID))
{
//編輯的保存
result = SaveUpdated();
}
else
{
//新增的保存
result = SaveAddNew();
}
return result;
}
/// <summary>
/// 更新已有的數據
/// </summary>
/// <returns></returns>
public virtual bool SaveUpdated()
{
return true;
}
/// <summary>
/// 保存新增的數據
/// </summary>
/// <returns></returns>
public virtual bool SaveAddNew()
{
return true;
}
/// <summary>
/// 保存
/// </summary>
/// <param name="close">關閉窗體</param>
private void SaveEntity(bool close)
{
// 檢查輸入的有效性
if (this.CheckInput())
{
// 設置鼠標繁忙狀態
this.Cursor = Cursors.WaitCursor;
try
{
if (this.SaveEntity())
{
ProcessDataSaved(this.btnOK, new EventArgs());
MessageDxUtil.ShowTips("保存成功");
if (close)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
this.ClearScreen();
}
}
}
catch (Exception ex)
{
this.ProcessException(ex);
}
finally
{
// 設置鼠標默認狀態
this.Cursor = Cursors.Default;
}
}
}
以上屬於基類的數據保存操作,我們特別注意這段代碼即可
if (this.SaveEntity())
{
ProcessDataSaved(this.btnOK, new EventArgs());
4)列表展現界面的操作實現
實現上面的操作後,這些就不需要在BaseEditForm的子類做任何操作了,只需要在具體的列表展現界面類中實現下面的代碼即可。
我們知道,列表界面一般都會有具體的數據刷新函數封裝(如BindData函數),那麼我們在新建數據的時候,實現代碼是這樣的。
/// <summary>
/// 新增數據操作
/// </summary>
private void btnAddNew_Click(object sender, EventArgs e)
{
FrmEditLaw dlg = new FrmEditLaw();
dlg.OnDataSaved += new EventHandler(dlg_OnDataSaved);
dlg.ShowDialog();
}
void dlg_OnDataSaved(object sender, EventArgs e)
{
BindData();
}
這樣我們在新窗體(數據添加、數據編輯)中維護數據的時候,一旦觸發保存操作,這些最新的數據記錄也在列表中展現出來了。
最後放上一個Winform開發框架的界面,供參考。