我們在做WinForm項目開發的時候,經常會發現有一些數據很多,需要通過不同的Tab頁面分類來實現數據的錄入和現實,例如體檢數據,可能包含外科、內科、眼科、耳鼻喉科、口腔科、以及其他的檢查等等內容,如果一次性放在一個窗口中現實,不太合理也不好看,如果通過多個Tab分類進行管理,則用戶體驗好很多。
PS:給大家推薦一個C#開發可以用到的界面組件——DevExpress WinForms,它能完美構建流暢、美觀且易於使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕鬆勝任!
DevExpress技術交流羣7:674691612 歡迎一起進羣討論
如果分爲多個Tab頁面進行數據管理,最好的方法是,每個頁面負責自己的數據存儲及顯示,由於數據可能是關聯的,存儲需要使用事務。保存的時候,可能每項都會有檢查數據是否完備及有效性。那麼我們應該實現類似這樣的界面操作呢。
如上分析,我們把每個模塊獨立出來做一個控件,如眼科的作爲一個獨立的用戶控件進行展現,如下所示。
其他模塊也一樣處理,獨立作爲一個用戶控件,然後再在一個主窗體界面中進行整合即可。
爲了對窗體能夠實現批量處理,我們需要爲每個用戶控件定義一個接口,他們之間都需要實現這些約定的接口,接口如下所示。
interface IDataApply { /// <summary> /// 設置控件的重要屬性 /// </summary> /// <param name="id">記錄ID</param> /// <param name="pilotId">飛行人員ID</param> /// <param name="isNewData">是否爲新建記錄</param> void SetData(string id, string pilotId, bool isNewData); /// <summary> /// 數據顯示的函數 /// </summary> void DisplayData(); /// <summary> /// 用於模塊事務性提交數據 /// </summary> /// <param name="trans">事務對象</param> /// <returns></returns> bool Apply(DbTransaction trans); /// <summary> /// 檢查輸入的有效性 /// </summary> /// <returns>有效</returns> bool CheckInput(); }
這樣,獨立的用戶控件需要繼承接口,實現接口約定的內容。
public partial class EyeControl : DevExpress.XtraEditors.XtraUserControl, IDataApply
我們來看其中一個TabPage的模塊接口實現代碼如下所示。
#region IDataApply 成員 /// <summary> /// 檢查輸入的有效性 /// </summary> /// <returns>有效</returns> public bool CheckInput() { bool result = true;//默認是可以通過 if (this.txtCheckDate.Text.Length == 0) { MessageDxUtil.ShowTips("請輸入體檢結論日期"); this.txtCheckDate.Focus(); return false; } return result; } /// <summary> /// 設置控件的重要屬性 /// </summary> /// <param name="id">記錄ID</param> /// <param name="pilotId">飛行人員ID</param> /// <param name="isNewData">是否爲新建記錄</param> public void SetData(string id, string pilotId, bool isNewData) { this.ID = id; this.Pilot_ID = pilotId; this.IsNewData = isNewData; } /// <summary> /// 數據顯示的函數 /// </summary> public void DisplayData() { InitDictItem();//數據字典加載(公用) if (!this.IsNewData) { #region 顯示客戶信息 LargeCheckConclusionInfo info = BLLFactory<LargeCheckConclusion>.Instance.FindByID(ID); if (info != null) { txtCheckDate.DateTime = info.CheckDate; txtDiagnosis.Text = info.Diagnosis; txtResult.Text = info.Result; txtSuggestion.Text = info.Suggestion; txtHealthLevel.Text = info.HealthLevel; txtHospital.Text = info.Hospital; } #endregion } else { } } /// <summary> /// 用於模塊事務性提交數據 /// </summary> /// <param name="trans">事務對象</param> /// <returns></returns> public bool Apply(DbTransaction trans) { this.trans = trans; bool result = false; if (!this.IsNewData) { //編輯的保存 result = SaveUpdated(); } else { //新增的保存 result = SaveAddNew(); } return result; } #endregion
其中我們注意到,各模塊的數據顯示及保存,都是自治的,這樣除了較好管理數據顯示及保存外,也使得主界面整合更加簡潔方便。
在主編輯界面中,我們需要逐一對各個控件的檢查,以及數據保存及顯示等操作進行處理,具體我們可以通過遍歷進行處理。
1)檢查控件輸入的部分如下代碼所示。
/// <summary> /// 檢查輸入的有效性 /// </summary> /// <returns>有效</returns> public virtual bool CheckInput() { bool result = true;//默認是可以通過 if (this.txtPilot.PilotID.Trim().Length == 0) { MessageDxUtil.ShowTips("請選擇飛行人員"); this.txtPilot.Focus(); result = false; } //檢查輸入是否正確 foreach (XtraTabPage page in this.xtraTabControl1.TabPages) { foreach (Control control in page.Controls) { IDataApply apply = control as IDataApply; if (apply != null) { apply.SetData(ID, this.txtPilot.PilotID, IsNewData); result = apply.CheckInput(); if (!result) { this.xtraTabControl1.SelectedTabPage = page; control.Focus(); } } } } return result; }
2)顯示每個控件負責的數據,操作代碼如下所示。
/// <summary> /// 顯示數據到控件上 /// </summary> public virtual void DisplayData() { InitDictItem();//數據字典加載(公用) foreach (XtraTabPage page in this.xtraTabControl1.TabPages) { foreach (Control control in page.Controls) { IDataApply apply = control as IDataApply; if (apply != null) { apply.SetData(ID, Pilot_ID, IsNewData); apply.DisplayData(); } } } }
3)採用事務性保存數據的實現代碼如下所示。
/// <summary> /// 保存數據(新增和編輯的保存) /// </summary> public virtual bool SaveEntity() { bool result = false; DbTransaction trans = BLLFactory<LargeCheckConclusion>.Instance.CreateTransaction(); if (trans != null) { try { foreach (XtraTabPage page in this.xtraTabControl1.TabPages) { foreach (Control control in page.Controls) { IDataApply apply = control as IDataApply; if (apply != null) { apply.SetData(ID, this.txtPilot.PilotID, IsNewData); apply.Apply(trans); } } } if (trans != null) { trans.Commit(); result = true; } } catch (Exception ex) { if (trans != null) { trans.Rollback(); } LogHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); return false; } } return result; }
實現以上的操作,基本上對控件的數據管理就差不多了,這樣比我們把全部雞蛋放到一個籃子裏面處理,會顯得更加清晰,更加高效,重要的是減少出錯的機會,否則想想看,如果操作的數據字段內容上百個,保存,顯示,檢查這些操作,是不是很容易漏掉,或者出現錯誤呢。況且把每部分雞蛋放到一個小籃子裏面,我們管理就是小籃子,這樣管理的對象減少了,效率也就提高了。
以上就是對於多個Tab頁面的數據處理解決方案,應該對大家有一定的啓發意義。
本文轉載自:博客園 - 伍華聰