其實也許咱們天天面對的太多東西了,以爲不少都稀鬆日常了,即便很細微的地方,可能咱們都已經造成習慣了。反過來,若是咱們切換到其餘領域,如IOS、android,那麼開始咱們可能對裏面不少設計的規則不甚瞭解,開始可能也是一頭霧水。html
本篇繼續上一篇《按部就班開發WinForm項目(3)--Winform界面層的項目設計》,繼續介紹如何按部就班開發Winform項目,繼續介紹Winform界面模塊如何整合到主體項目工程裏面,進行使用等操做,使得咱們逐漸瞭解一個完整的開發方案過程。android
上篇介紹瞭如何利用工具進行Winform界面層窗體的快速生成,並進行適當的調整,已達到合理佈局,顯示美觀等的效果,本篇繼續這一主題介紹下去,上篇咱們開發好的獨立界面模塊,如何在主體項目中集成使用呢?數據庫
首先咱們把生成的界面層DLL複製到項目工程中,而後在主項目工程中添加相關的應用,以下所示。緩存
而後,咱們須要作的就是,在主體界面模塊裏面添加一個功能按鈕的入口,以下所示是我在個人框架界面啓動模塊裏面添加一個按鈕的效果。框架
而後在按鈕的單擊事件裏面,添加下面的代碼便可。數據庫設計
private void tool_Customer_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { ChildWinManagement.LoadMdiForm(this, typeof(WHC.TestProject.UI.FrmCustomer)); }
其中ChildWinManagement是公用類庫裏面一個輔助類,用來在多文檔的狀況下進行窗體的展現,傳入一個MDI的Parent的窗體對象引用,另一個是構造顯示的窗體類型,它會根據類型來判斷是否已經實例化了,若是存在就打開,不然就建立一個新的窗體病顯示出來主界面裏面。ide
啓動界面,後看到的效果以下所示(咱們在後臺添加一些測試數據後)。模塊化
雙擊數據出來的編輯界面以下所示。函數
這樣,咱們在尚未添加任何代碼和邏輯實現的狀況下,基本的界面已經出來了,並且相關的數據存儲和顯示的功能已經存在,咱們所須要作的就只是細化裏面的內容便可。工具
第一節中介紹的是傳統方式的界面模塊的繼承,開發框架自己也還提供了另一種方式的界面模塊集成方式,插件化的模塊化集成。咱們經過把相關的DLL複製到運行的目錄下,而且在數據庫裏面配置好相關的Winform模塊信息後,就能夠在主界面中調用出來是用來。
關於插件化的框架實現的介紹,你們能夠看看我前面寫的一篇博客文章《Winform開發框架之插件化應用框架實現》。
首先咱們配置菜單的時候,登錄權限管理系統,添加相關的菜單項目,以下所示。固然,若是你有本身的菜單管理模塊,本身經過本身的手工設置好相關的信息便可。
好,搞定菜單的動態配置後,咱們從新登錄下系統的主界面,看看有無變化了。
從主界面的Ribbon工具欄,咱們能夠看到,裏面已經新增了一個客戶管理(紅色部分)的內容了,這個位置就是咱們剛纔新增菜單的位置。單擊菜單按鈕,那麼就會展示出來客戶管理的內容了。
整個主界面框架,加上打開的客戶管理界面,總體的效果是一個多文檔的界面效果。
前面幾篇的隨筆,主要就是介紹給咱們認識如何快速開發一個模塊,而且集成到系統框架裏面進行使用,咱們甚至尚未開始編碼,就已經給咱們處理好不少細節上的東西,基本上就已經完成一個業務小模塊的展現工做了。
完成本文的前面兩個小節,不知道大家有沒有發現,咱們好像尚未真正的整合登錄的用戶信息呢?在獨立的系統模塊開發過程當中,咱們如何整合登錄的用戶信息呢?
咱們從新回到開發的業務模塊的界面項目裏面看看原來的編輯界面代碼。
這裏面對於保存新增的數據,咱們調整一下,把它的建立的人員和時間在代碼FrmEditCustomer.cs裏面調整成合理的代碼,記錄人員和當前時間。
/// <summary> /// 編輯或者保存狀態下取值函數 /// </summary> /// <param name="info"></param> private void SetInfo(CustomerInfo info) { info.Name = txtName.Text; info.Age = txtAge.Value.ToString().ToInt32(); } /// <summary> /// 新增狀態下的數據保存 /// </summary> /// <returns></returns> public override bool SaveAddNew() { CustomerInfo info = tempInfo;//必須使用存在的局部變量,由於部分信息可能被附件使用 SetInfo(info); info.CreateTime = DateTime.Now; info.Creator = LoginUserInfo.ID.ToString();//爲了更好管理,咱們這裏存儲用戶的ID,而非名稱 try { #region 新增數據 bool succeed = BLLFactory<Customer>.Instance.Insert(info); if (succeed) { //可添加其餘關聯操做 return true; } #endregion } catch (Exception ex) { LogTextHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); } return false; }
其中紅色部分就是咱們新增的內容,我在代碼裏面存儲當前登錄用戶的ID:LoginUserInfo.ID.ToString()。
這裏的LoginUserInfo是窗體基類的一個屬性,這個屬性經過兩種方式得到,一個是經過用戶在調用窗體顯示前進行指定,一種是經過基類自動把緩存裏面的用戶對象賦值。
以下面的代碼就是界面基類BaseForm的部分代碼。
namespace WHC.Framework.BaseUI { /// <summary> /// 常規界面基類 /// </summary> public partial class BaseForm : DevExpress.XtraEditors.XtraForm, IFunction { public event EventHandler OnDataSaved;//子窗體數據保存的觸發 public BaseForm() { InitializeComponent(); //爲了保證一些界面控件的權限控制和身份確認,以及簡化操做,在界面初始化的時候,從緩存裏面內容(若是存在的話) //繼承的子模塊,也能夠經過InitFunction()進行指定用戶相關信息 this.LoginUserInfo = Cache.Instance["LoginUserInfo"] as LoginUserInfo; this.FunctionDict = Cache.Instance["FunctionDict"] as Dictionary<string, string>; }
這些用戶和功能的信息來源於登錄主界面的時候,咱們把它們進行了緩存,方便基類窗體進行獲取。
Portal.gc.LoginUserInfo = Portal.gc.ConvertToLoginUser(info); Cache.Instance.Add("LoginUserInfo", Portal.gc.LoginUserInfo);//緩存用戶信息,方便後續處理 Cache.Instance.Add("FunctionDict", Portal.gc.FunctionDict);//緩存權限信息,方便後續使用
第二種方式指定當前用戶信息的步驟,是經過基類窗體的InitFunction函數進行指定。
/// <summary> /// 初始化權限控制信息 /// </summary> public void InitFunction(LoginUserInfo userInfo, Dictionary<string, string> functionDict) { if (userInfo != null) { this.LoginUserInfo = userInfo; } if (functionDict != null && functionDict.Count > 0) { this.FunctionDict = functionDict; } }
手工指定當前用戶信息的調用代碼以下所示。
private void btnAddNew_Click(object sender, EventArgs e) { FrmEditCustomer dlg = new FrmEditCustomer(); dlg.InitFunction(base.LoginUserInfo, base.FunctionDict);//該步驟省略也能夠,用戶信息以經過基類緩存進行獲取 if (DialogResult.OK == dlg.ShowDialog()) { BindData(); } }
通常狀況下,咱們建議採用第一種,不用多餘的代碼進行設置指定,只須要在登陸的時候,把它放到緩存裏面便可,這樣界面基類實例化的時候,就會自動獲取用戶信息了,這個操做相似於Web領域裏面的Session操做,只要存儲/獲取的鍵值保存一致便可。
好了,咱們前面說到,保存的時候,是保存當前用戶的ID信息,那麼咱們在列表展現的時候,默認就會展現用戶的ID信息而已,獲得的界面效果以下所示。
咱們爲了更好展現內容,就須要對用戶ID的數據進行轉義。
因爲DevExpress有這樣對每行記錄進行轉義的操做,咱們在列表界面上添加一個轉義函數。
this.winGridViewPager1.gridView1.CustomColumnDisplayText += new DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventHandler(gridView1_CustomColumnDisplayText);
數據轉義函數裏面涉及到對權限系統模塊的引用(咱們須要把ID轉義爲FullName(用戶全名)),咱們把權限模塊的DLL引用包含進來便可(由於權限管理模塊是全部界面模塊均可以使用的)。
而後在這個函數裏面對當前的Creator進行轉義。
void gridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e) { if (e.Column.ColumnType == typeof(DateTime)) { string columnName = e.Column.FieldName; if (e.Value != null) { if (Convert.ToDateTime(e.Value) <= Convert.ToDateTime("1900-1-1")) { e.DisplayText = ""; } else { e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm");//yyyy-MM-dd } } } else if (e.Column.FieldName == "Creator") { if (e.Value != null) { e.DisplayText = BLLFactory<User>.Instance.GetFullNameByID(e.Value.ToString().ToInt32()); } } }
而後複製文件,從新運行主程序便可看到以下界面所示。
至此,咱們本小節已經完成了,登錄用戶信息的記錄和轉義的操做了,固然咱們系統模塊裏面,可能還有不少地方須要用到用戶信息的或者角色信息的,這個例子只是一個拋磚引玉的操做。
按部就班開發WInform項目--系列文章導引:
《按部就班開發WinForm項目(4)--Winform界面模塊的集成使用》