本文實例講述了C#遞歸讀取XML菜單數據的方法。分享給大家供大家參考。具體分析如下:
最近在研究一些關于C#的一些技術,縱觀之前的開發項目的經驗,做系統時顯示系統菜單的功能總是喜歡把數據寫在數據庫表,然后直接讀取加載到菜單樹上顯示。
現在想把菜單數據都放在XML里,然后遞歸讀取XML。
由于項目使用WCF,實體類使用了兩個,一個是業務邏輯層中的實體,一個是調用業務邏輯層遞歸方法后進行數據實體的轉換,XML讀取方法寫在業務邏輯層中。
思路:
1.先讀取XML里所有的菜單
2.根據用戶的權限顯示所屬用戶的菜單加載到頁面上
XML數據如下:
<Module ID="OA_TargetManage" Text="目標管理">
<Menus>
<Menu ID="OA_TargetManage_TargetSetup" Text="目標設定" URL="OA/TargetManage/TargetSetupList.aspx">
</Menu>
</Menus>
</Module>
</Modules>
</Application>
</ZCSoft.Net>
菜單的業務邏輯實體類:
//菜單名稱
public string ItemName { get; set; }
//菜單顯示類型
public string ItemType { get; set; }
//排序
public int ItemOrder { get; set; }
//是否顯示
public bool Visible { get; set; }
//菜單鏈接
public string ItemUrl { get; set; }
//上級ID
public string ParentItem { get; set; }
//系統平臺ID
public string ApplicationCode { get; set; }
//系統平臺名稱
public string ApplicationName { get; set; }
//模塊ID
public string ModuleCode { get; set; }
//模塊名稱
public string ModuleName { get; set; }
}
遞歸方法,讀取每個模塊和模塊下的菜單:
bool thisVisible = true;//默認節點是可見的
XAttribute thisAttr = root.Attribute("Display");
if (null != thisAttr)//如果菜單的上級模塊有顯示屬性
{
string thisDisplay = thisAttr.Value;
thisVisible = thisDisplay.ToLower() == "false" ? false : true;
}
foreach (var application in appList)
{
//模塊Display屬性
XAttribute modAttr = application.Attribute("Display");
bool visible = true;
if (null != modAttr)
{
string display = application.Attribute("Display").Value;
visible = display.ToLower() == "false" ? false : true;
}
var nextNode = application.FirstNode as XElement;//該節點的下級節點
string itemType = "Folder";//目錄還是菜單
string itemUrl = null;//鏈接地址
string parentItem = null;//上一節點ID
string applicationCode = null;//平臺編碼
string applicationName = null;//平臺名稱
string moduleCode = null;//模塊編碼
string moduleName = null;//模塊名稱
if (application.Name.LocalName == "Application")
{
applicationCode = application.Attribute("ID").Value;
applicationName = application.Attribute("Text").Value;
}
if (application.Name.LocalName == "Module")
{
moduleCode = application.Attribute("ID").Value;
moduleName = application.Attribute("Text").Value;
applicationCode = root.Attribute("ID").Value;
applicationName = root.Attribute("Text").Value;
if (thisVisible) //如果該模塊的所屬平臺中的Display屬性設置為可見true(注意:沒有設置則默認為可見),則模塊的上級為Application的ID
{
parentItem = root.Attribute("ID").Value;
}
}
if (application.Name.LocalName == "Menu")
{
itemType = "Menu";
itemUrl = application.Attribute("URL").Value;
moduleCode = root.Attribute("ID").Value;
moduleName = root.Attribute("Text").Value;
applicationCode = root.Parent.Parent.Attribute("ID").Value;
applicationName = root.Parent.Parent.Attribute("Text").Value;
if (thisVisible) //如果該菜單的所屬模塊中的Display屬性設置為可見true(注意:沒有設置則默認為可見),則菜單的上級為Module的ID
{
parentItem = root.Attribute("ID").Value;
}
else//如果該菜單的所屬模塊中的Display屬性設置為不可見false,則菜單的上級為Application的ID
{
parentItem = root.Parent.Parent.Attribute("ID").Value;
}
}
MenuTreeSearchModel model = new MenuTreeSearchModel();
model.ItemCode = application.Attribute("ID").Value;
model.ItemName = application.Attribute("Text").Value;
model.ItemType = itemType;
model.ItemOrder = 0;
model.Visible = visible;
model.ItemUrl = itemUrl;
model.ParentItem = parentItem;
model.ApplicationCode = applicationCode;
model.ApplicationName = applicationName;
model.ModuleCode = moduleCode;
model.ModuleName = moduleName;
menuTreeList.Add(model);
if (null != nextNode)//如果還有下級節點
{
//調用遞歸
GetChildMenuList(application, menuTreeList);
}
}
}
}
從XML文檔讀?。?/p>
//遞歸調用
GetChildMenuList(application, list);
}
return list;
}
以下是在調用服務契約方法時進行的實體類:
//菜單名稱
public string ItemName { get; set; }
//菜單顯示類型
public string ItemType { get; set; }
//排序
public int ItemOrder { get; set; }
//是否顯示
public bool Visible { get; set; }
//菜單鏈接
public string ItemUrl { get; set; }
//上級ID
public string ParentItem { get; set; }
//系統平臺ID
public string ApplicationCode { get; set; }
//系統平臺名稱
public string ApplicationName { get; set; }
//模塊ID
public string ModuleCode { get; set; }
//模塊名稱
public string ModuleName { get; set; }
//當前菜單下的菜單集合
public List<PublicUserMenuTreeData> UserMenuTreeDatas { set; get; }
}
實體轉換方法:
用戶權限菜單方法:
List<MenuTreeData> list = listUserMenuTreeData.FindAll(d => d.ParentItem == parentId).ToList();
if (list.Count > 0)
{
List<PublicUserMenuTreeData> listPublicUserMenuTreeData = new List<PublicUserMenuTreeData>();
foreach (var userMenuTreeData in list)
{
PublicUserMenuTreeData pubUserMenuTreeData = TransferUserMenuTreeToPublicUserMenu(userMenuTreeData);
pubUserMenuTreeData.UserMenuTreeDatas = GetChildData(pubUserMenuTreeData.ItemCode, listUserMenuTreeData);
listPublicUserMenuTreeData.Add(pubUserMenuTreeData);
}
return listPublicUserMenuTreeData;
}
return null;
}
系統菜單類:
[DataMember()]
public string ItemCode { get; set; }
[DataMember()]
public string ItemName { get; set; }
[DataMember()]
public string ItemType { get; set; }
[DataMember()]
public int ItemOrder { get; set; }
[DataMember()]
public bool Visible { get; set; }
[DataMember()]
public string ItemUrl { get; set; }
[DataMember()]
public string ParentItem { get; set; }
[DataMember()]
public string ApplicationCode { get; set; }
[DataMember()]
public string ApplicationName { get; set; }
[DataMember()]
public string ModuleCode { get; set; }
[DataMember()]
public string ModuleName { get; set; }
}
后臺頁面加載Load代碼:
頁面加載腳本,這里使用Jquery:
str += (" id: 'oa-system-" + tempmenu.ItemCode + "',");
str += (" closable: true }); jQuery('#mainmenulist').hide(); return false; }<//script>");
} else {
str += ("<a href='#' id='" + PublicUserMenuTreeData[i].ItemCode + "'>" + PublicUserMenuTreeData[i].ItemName + "</a>");
}
if (PublicUserMenuTreeData[i].UserMenuTreeDatas) {
str += GetRecurrenceData(PublicUserMenuTreeData[i].UserMenuTreeDatas);
}
str += (" </li>");
}
}
}
function GetRecurrenceData(listPublicUserMenuTreeData) {
var str = "";
if (listPublicUserMenuTreeData && listPublicUserMenuTreeData.length>0) {
str += (" <ul>");
for (var j = 0; j < listPublicUserMenuTreeData.length; j++) {
str += ("<li class='divFontWeight'>");
if (listPublicUserMenuTreeData[j].ItemType && listPublicUserMenuTreeData[j].ItemType == "Menu") {
str += ("<a href='#' onclick='" + listPublicUserMenuTreeData[j].ItemCode + "()' id='" + listPublicUserMenuTreeData[j].ItemCode + "'>" + listPublicUserMenuTreeData[j].ItemName + "</a>");
str += ("<script> function " + listPublicUserMenuTreeData[j].ItemCode);
str += ("() { tabframe1.newTab({ title: '" + listPublicUserMenuTreeData[j].ItemName + "',");
if (listPublicUserMenuTreeData[j].ItemUrl.indexOf('?') != -1) {
str += ("src: '" + listPublicUserMenuTreeData[j].ItemUrl + "&applicationid=" + listPublicUserMenuTreeData[j].ApplicationCode + "&moduleid=" + listPublicUserMenuTreeData[j].ModuleCode + "',");
} else {
str += ("src: '" + listPublicUserMenuTreeData[j].ItemUrl + "?applicationid=" + listPublicUserMenuTreeData[j].ApplicationCode + "&moduleid=" + listPublicUserMenuTreeData[j].ModuleCode + "',");
}
str += (" id: 'oa-system-" + listPublicUserMenuTreeData[j].ItemCode + "',");
str += (" closable: true }); jQuery('#mainmenulist').hide(); return false; }<//script>");
} else {
str += ("<a href='#' id='" + listPublicUserMenuTreeData[j].ItemCode + "'>" + listPublicUserMenuTreeData[j].ItemName + "</a>");
}
var ListMenuDatas = listPublicUserMenuTreeData[j].UserMenuTreeDatas;
str += GetRecurrenceData(ListMenuDatas);
str += ("</li>");
}
str += (" </ul>");
}
return str;
}
效果圖:
這里補充一下:菜單中如果在模塊Module里設置屬性Display="false",則模塊不顯示出來,可是模塊下的菜單可顯示出來。
itemType="Folder"顯示類型是目錄,itemType="Menu"顯示類型是菜單
希望本文所述對大家的C#程序設計有所幫助。
新聞熱點
疑難解答