在我的隨筆中,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開發框架的界面,供參考。