在我們一般的應用系統裡面,由于系統是面向不同類型的使用者,我們所看到的菜單會越來越多,多一點的甚至上百個,但是我們實際工作接觸的菜單可能就是那麼幾個,那麼對于這種龐大的菜單體系,尋找起來非常不便。是以對菜單的個性化配置就顯得尤為重要,本篇随筆就是基于這樣的理念,提供使用者對可見菜單進行一個動态配置,隻選自己喜歡、常用的菜單顯示出來即可,菜單的配置存儲在資料庫裡面,在不同的用戶端體驗都是一樣。本篇随筆主要介紹實作這樣的功能的一個完整思路,部分代碼邏輯可供參考。
在我們有些軟體裡面,我們可能在界面上頂部放置菜單,也可能在界面的左側放置樹形清單菜單,這種情況都有可能,本篇摘取其中之一,左側菜單進行一個介紹菜單的配置處理。
例如我們在左側根據使用者權限展示相關的菜單資訊,動态生成整個清單展示,大緻的界面效果如下所示。

然後在功能清單上提供一個右鍵的菜單進行菜單的重新整理、配置管理,如下界面所示。
通過配置功能,我們讓使用者進入一個配置管理界面,在其中配置顯示自己感興趣的菜單,然後進行儲存即可,儲存後同時重新整理界面的功能菜單顯示。
以上幾個界面效果就是為了介紹整個菜單配置管理的一般過程,之是以把界面效果放在前面介紹,就是能夠讓我們有一個類似原型設計方式的感性認識,了解了相關的處理過程,我們就可以着手通過編碼的方式來實作這個處理邏輯了。
上面介紹了大概的界面效果,有了參考,我們可以把它的實作思路通過代碼實作出來。
首先我們需要了解,使用者配置可以通過XML儲存在本地,也可以通過資料庫存儲儲存在伺服器,後者在分布式的用戶端的時候,可以處處一樣,這樣就不會造成體驗上的差異,是以我們這裡采用存儲在資料庫的方案。
這個配置管理元件SettingsProvider.net使用起來也是比較友善的,可以選擇存儲在本地的對象,也可以選擇存儲在資料庫的存儲對象。
首先我們先定義一個存儲的參數類,這個是使用這個元件所必須的存儲對象資訊,如下代碼所示。
需要擷取或存儲這個對象資訊的時候,我們初始化幾個管理類,如下代碼所示。
然後在配置管理界面窗體裡面,初始化這幾個對象,如下代碼所示。
這樣我們就可以根據使用者的ID,擷取對應記錄的資訊并轉換為相關的對象了,如果我們需要把修改的資訊寫會到存儲媒體裡面,代碼如下所示。
解決了參數的擷取及存儲功能後,我們需要編寫一個界面來管理使用者的菜單配置,也就是我們前面介紹的菜單配置管理界面。
我們這個界面的定義代碼如下所示。
其中參數的資料存儲就是應用了前面介紹的代碼,這裡需要根據使用者的配置項初始化樹形菜單的顯示處理,通過InitTree的函數實作菜單的顯示。
在顯示菜單前,我們先介紹一下功能菜單顯示的規則,僅當參數存在對應記錄,并且該記錄顯式設定不可見,菜單才不可見,否則預設菜單是可以看到的。
這樣確定了,在參數沒有配置前,所有的菜單對目前使用者是可見的,隻有使用者設定為不不可見,該菜單才不顯示為不可見。
顯示菜單的相關處理邏輯,就是根據上面的判斷,然後确定是否勾選記錄,如下代碼所示。
存儲使用者勾選的記錄的時候,我們需要周遊整個樹節點,判斷勾選了那些選項,然後把它儲存資料庫即可。
參數的儲存操作如下所示。
以上處理完成後,我們在主界面的工具欄右鍵菜單添加一個菜單項,用來進入配置界面的,如下邏輯代碼所示。
這樣界面配置參數并儲存後,界面的樹形菜單會及時得到更新處理。
另外,我們主界面的樹形清單,也要根據配置參數的資訊作相關的調整,如果使用者配置了不顯示某個菜單,那麼主界面也要根據配置參數控制顯示。
以上就是整個菜單清單的動态個性化配置管理的整體思路和實作步驟代碼,主要的界面考量還是以使用者的視覺來考慮界面的布局和功能,如果在幾百個菜單項中尋找幾個常用的菜單,每次是一個比較耗時無聊的操作,是以提供一個個性化的界面,根據工作情況的不同,顯示一些和自己相關的功能即可。
例如有些情況下,我們的菜單顯示,希望通過工具欄的方式進行控制顯示,如下界面效果所示。
那麼配置維護界面還是差不多,隻是我們控制工具欄的顯示邏輯有所不同而已,對于RibbonPage及其功能菜單的動态生成處理如下所示。
本篇随筆主要還是希望讀者借鑒配置存儲和菜單個性化管理的思路,具體的邏輯會因使用者界面的不同,使用的控件不同而有所差異,不過總體思路是一緻的即可。
例如有些參數的配置管理,可以統一使用一個配置管理界面進行維護,如我之前的随筆介紹的界面功能一樣。