在Winform的分頁控制項裡面,我們提供了很多豐富的功能,如常規分頁,中文轉義、導出Excel、導出PDF等,基於DevExpress的樣式的分頁控制項,我們在其上面做了不少封裝,以便更好的使用,其中就包括集成保存用戶列表顯示欄位及寬度調整設置。本篇隨筆介紹這個實現的過程,通過在當前程式中序列化方式存... ...
在Winform的分頁控制項裡面,我們提供了很多豐富的功能,如常規分頁,中文轉義、導出Excel、導出PDF等,基於DevExpress的樣式的分頁控制項,我們在其上面做了不少封裝,以便更好的使用,其中就包括集成保存用戶列表顯示欄位及寬度調整設置。本篇隨筆介紹這個實現的過程,通過在當前程式中序列化方式存儲一個記錄用戶設置的文件,提供介質的存儲和載入處理。
1、集成保存用戶列表顯示欄位及寬度調整設置的需求
在一些用戶列表使用的反饋中,希望能夠在調整列表欄位和它的順序,以及能夠保存上次調整記錄的寬度,因此,涉及到欄位可見列表、欄位順序,列寬度的內容保存,這些功能應該是對用戶透明的,不需要開發人員干預,也不需要用戶過多操作就能實現的,也就是在用戶調整的時候,自動記錄這些信息,並存儲起來,下一次打開頁面的時候,自動載入上次的設置信息即可,邏輯也算比較簡單。
因此我們需要檢測用戶對列寬度調整的事件,記錄列欄位寬度的信息,如果用戶調整欄位顯示和順序,那麼控制項也需要對它進行記錄起來,供下次載入使用。
對於DevExpress的列寬調整,有一個事件,我們在控制項邏輯中實現它,記錄它的變化並存儲即可
this.gridView1.ColumnWidthChanged += GridView1_ColumnWidthChanged;
然後我們在事件的實現中,判斷用戶是否啟用自定義設置處理,然後進行存儲列寬處理即可。
private void GridView1_ColumnWidthChanged(object sender, DevExpress.XtraGrid.Views.Base.ColumnEventArgs e) { //如果不設置,預設不處理 if (!this.EnableColumnsSetting) return; GridViewHelper.SaveColumnSetting(this.gridView1, this.ParentForm?.Name); }
為了方便,我們把一些邏輯分離到一個獨立的輔助文件上,實現代碼如下所示。
/// <summary> /// 保存列設置 /// </summary> /// <param name="settings">當前設置信息</param> /// <param name="gridViewName">視圖名稱</param> /// <param name="parentFormName">父類窗體名稱,用於區分</param> public static void SaveColumnSetting(GridColumnSetting settings, string gridViewName, string parentFormName) { if (settings != null) { var folderPath = $"{Environment.CurrentDirectory}/ColumnSetting"; var filePath = $"{folderPath}/{parentFormName}.{gridViewName}.setting"; // 檢查文件夾是否存在 if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } using (var stream = new FileStream(filePath, FileMode.Create)) { var formatter = new BinaryFormatter(); formatter.Serialize(stream, settings); } } }
上面主要就是對設置信息進行序列化到一個文件中進行中轉,從而避免資料庫的處理,同時又會因為不同用戶記錄不同的設置信息。對於不同的頁面,我們通過表單名稱來區分不同的設置,因為分頁控制項場景需要一個唯一的標識來區分不同的數據場景。
而對於可見欄位,以及它的順序調整,那麼我們為了方便,提供一個設置的界面給終端用戶使用即可,通過列表右鍵菜單觸發入口,如下界面所示。
在列表框中列出界面的所有列(包括隱藏列),並通過拖動或者按鈕調整順序,通過勾選設置可見性,如下界面所示。
上面的列表控制項,是一個標準的CheckedListBox控制項,通過處理它的拖動事件,實現可拖動順序的調整。
// 綁定 ListBoxControl 控制項的事件,實現拖拉處理 listBoxControl.DragDrop += ListBoxControl_DragDrop; listBoxControl.DragOver += ListBoxControl_DragOver; listBoxControl.MouseDown += ListBoxControl_MouseDown;
而讀取上面的列表中的可見列欄位及順序,我們通過配置文件中進行讀取,並反序列化即可。
/// <summary> /// 獲取配置信息 /// </summary> /// <param name="gridView">當前視圖</param> /// <param name="parentFormName">父類窗體名稱,用於區分</param> /// <returns></returns> public static GridColumnSetting GetSettings(GridView gridView, string parentFormName) { var folderPath = $"{Environment.CurrentDirectory}/ColumnSetting"; var filePath = $"{folderPath}/{parentFormName}.{gridView.Name}.setting"; if (!File.Exists(filePath)) return null; //反序列化 GridColumnSetting settings = null; using (FileStream stream = new FileStream(filePath, FileMode.Open)) { var formatter = new BinaryFormatter(); settings = (GridColumnSetting)formatter.Deserialize(stream); } return settings; }
對於用戶調整後的設置保存,記錄好相關信息後進行序列化到文件中即可,如下實現邏輯所示。
private void btnOK_Click(object sender, EventArgs e) { //記錄所有的列寬 var sb = new StringBuilder(); var visibleSb = new StringBuilder(); int index = 0; foreach (var objItem in this.listBoxControl.Items) { var item = objItem as CListItem; if (item != null) { var checkState = this.listBoxControl.GetItemChecked(index); if (checkState) { var column = this.GridView.Columns.ColumnByFieldName(item.Value); if (column != null) { sb.Append($"{item.Value}:{column.Width},"); visibleSb.Append($"{item.Value},"); } } } index++; } var columnsWidth = sb.ToString().Trim(','); var columnsVisbile = visibleSb.ToString().Trim(','); var settings = new GridColumnSetting(columnsWidth, columnsVisbile); //如果不設置,預設不處理 GridViewHelper.SaveColumnSetting(settings, this.GridView.Name, this.Owner?.Name); }
最終,我們在開發具體頁面數據展示的時候,把分頁控制項拖動到界面上就可以了,預設具有這些效果,不需要另外增加實現代碼,從而通過封裝的方式,簡化了很多基礎的功能處理,並能夠給用戶一致的體驗和界面效果。
專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
轉載請註明出處:撰寫人:伍華聰 http://www.iqidi.com