轉(zhuǎn)帖|其它|編輯:郝浩|2010-09-20 10:45:06.000|閱讀 661 次
概述:本文將介紹如何用Asp.net制作頂部導(dǎo)航控件,希望對(duì)大家有幫助。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
一、效果簡(jiǎn)介
當(dāng)點(diǎn)擊一級(jí)欄目時(shí)(如金喜正規(guī)買球),被點(diǎn)擊的一級(jí)欄目的單元格背景色發(fā)生變色,如果該一級(jí)欄目下有二級(jí)欄目,則會(huì)在下一行顯示出來(lái),否則二級(jí)欄目這一行不會(huì)顯示任何東西,但會(huì)占一定的高度。當(dāng)點(diǎn)擊二級(jí)欄目時(shí),其所屬的一級(jí)欄目單元格背景色發(fā)生變化,同時(shí)被點(diǎn)擊的二級(jí)欄目名稱會(huì)加粗,并在前方加一個(gè)“。”號(hào),表示現(xiàn)在正在訪問該欄目。當(dāng)前位置會(huì)隨著欄目的變化而變化。為了讓該控件更靈活,我用了xml,這樣就可以和數(shù)據(jù)庫(kù)脫離開來(lái),目前該用戶控件只能適應(yīng)一個(gè)頁(yè)面一個(gè)鏈接這種類型的網(wǎng)站,如果有“article.aspx?id=”這種形式的鏈接,則該控件不可用。
二、思路分析
用 Request.Url.AbsolutePath.ToString() 可以獲得當(dāng)前訪問的地址,比如當(dāng)前訪問地址為://localhost/temp/default.aspx,該方法即可獲得 temp/default.aspx 這一段,然后用LastIndexOf(@"/") 方法把訪問的文件名截出來(lái),這里就是指 default.aspx 這部份。有了訪問文件,就可以查出這個(gè)文件對(duì)應(yīng)的那條記錄,根據(jù)該記錄判斷它是一級(jí)欄目還是二級(jí)欄目,即可知道當(dāng)前點(diǎn)擊的是一級(jí)欄目還是二級(jí)欄目。然后顯示相應(yīng)的一級(jí)欄目和二級(jí)欄目即可實(shí)現(xiàn)上圖的效果。下面來(lái)具體分析實(shí)現(xiàn)代碼。
三、實(shí)現(xiàn)過(guò)程
1.xml文件代碼
<?xml version="1.0" encoding="gb2312" ?>
<siteMap>
<siteMapNode LinkUrl="default.aspx" Title="金喜正規(guī)買球" Parents="root" OrderID="1" />
<siteMapNode LinkUrl="soft.aspx" Title="軟件應(yīng)用" Parents="root" OrderID="2" />
<siteMapNode LinkUrl="hardsoft.aspx" Title="硬件相關(guān)" Parents="root" OrderID="5" />
<siteMapNode LinkUrl="system.aspx" Title="操作系統(tǒng)" Parents="root" OrderID="9" />
<siteMapNode LinkUrl="duomeiti.aspx" Title="多媒體類" Parents="root" OrderID="10" />
<siteMapNode LinkUrl="qq.aspx" Title="QQ專區(qū)" Parents="root" OrderID="11" />
<siteMapNode LinkUrl="security.aspx" Title="網(wǎng)絡(luò)安全" Parents="root" OrderID="12" />
<siteMapNode LinkUrl="other.aspx" Title="其它分類" Parents="root" OrderID="13" />
<siteMapNode LinkUrl="soft.aspx" Title="軟件技巧" Parents="軟件應(yīng)用" OrderID="3" />
<siteMapNode LinkUrl="softuse.aspx" Title="軟件使用" Parents="軟件應(yīng)用" OrderID="4"></siteMapNode>
<siteMapNode LinkUrl="hardsoft1.aspx" Title="硬件保養(yǎng)" Parents="硬件相關(guān)" OrderID="6"></siteMapNode>
<siteMapNode LinkUrl="hardsoft2.aspx" Title="硬件維護(hù)" Parents="硬件相關(guān)" OrderID="7"></siteMapNode>
<siteMapNode LinkUrl="hardsoft_other.aspx" Title="硬件其它" Parents="硬件相關(guān)" OrderID="8"></siteMapNode>
</siteMap>
Title 指的是欄目名稱,LinkUrl 指的是鏈接地址,Parents 指的是上級(jí)欄目,OrderID 指排序 ID。具體用法請(qǐng)看壓縮包內(nèi)的使用說(shuō)明。
2.添加用戶自定義控件及后臺(tái)代碼
通過(guò)“新建->項(xiàng)目->Visual C#項(xiàng)目->Asp.net Web 應(yīng)用程序”新建一個(gè)項(xiàng)目命令為 HeadControl,新建用戶自定義控件,命名為 Head.ascx。向 Head.ascx 頁(yè)面加入兩個(gè) label 控件,上面的命名為 lblCode,用來(lái)顯示后臺(tái)生成的一級(jí)欄目和二級(jí)欄目的代碼。下面的命名為 lblPosition,用來(lái)顯示當(dāng)前位置這一部份。如果沒有在 CSS 中定義頁(yè)面的上下左右距離,則需要手動(dòng)設(shè)置 Head.ascx頁(yè)面四邊的距離,要保證控件寬度在 Head.ascx 里為100%。也就是說(shuō),這個(gè)用戶控件不能有固定寬度,否則就不能適應(yīng)各種寬度網(wǎng)頁(yè)的需要。
接下來(lái)要在 Head.ascx.cs 中編碼,由于源碼較長(zhǎng),這里我就拿關(guān)鍵部份進(jìn)行解釋。
先在成員中創(chuàng)建一個(gè) DataSet 對(duì)象,代碼中好多地方要用到這個(gè) DataSet。
//創(chuàng)建 DataSet 對(duì)象
private DataSet ds = new DataSet();
然后定義讀取 xml 中的數(shù)據(jù)的方法,該方法傳入 xml 文件的相對(duì)路徑,查詢的條件以及排列方式,返回 DataView。
public DataView ReadXmlDataView(string strXmlPath,string strWhere,string strSort)
{
DataSet ds = new DataSet();
//讀入xml 的架構(gòu)
ds.ReadXmlSchema(Server.MapPath(strXmlPath));
//將 OrderID 列轉(zhuǎn)成整型(原本為字符串,影響排序),如果你排序不用 OrderID,請(qǐng)將這里的 OrderID 改成別的名稱,同時(shí) xml 文件里的 OrderID 也要改名
ds.Tables[0].Columns["OrderID"].DataType = System.Type.GetType("System.Int32");
//讀取 xml 文件
ds.ReadXml(Server.MapPath(strXmlPath));
DataView dv = new DataView();
//指定 DataView 的 Table 為 DataSet 的 Table
dv.Table = ds.Tables[0];
//指定 DataView 中的數(shù)據(jù)的排序方式
dv.Sort = strSort;
//指定 DataView 過(guò)濾數(shù)據(jù)條件,也就是進(jìn)行篩選
dv.RowFilter = strWhere;
//返回 DataView
return dv;
}
現(xiàn)在已經(jīng)可以讀出欄目數(shù)據(jù)了,接下來(lái)要寫五個(gè)方法來(lái)顯示欄目,分別為:
方法1:顯示所有一級(jí)欄目
該方法是點(diǎn)擊“金喜正規(guī)買球”時(shí)或者是第一次打開網(wǎng)頁(yè)的時(shí)候調(diào)用的,實(shí)現(xiàn)的效果為加粗“金喜正規(guī)買球”兩字,并改變“金喜正規(guī)買球”所在的單元格的背景。該方法命名為:showFirstMenu(),代碼如下:
public void showFirstMenu()
{
//讀取所有 Parents為root 的記錄(也就是所有一級(jí)欄目),升序排列,下同
DataView dv = ReadXmlDataView("HeadMenu.xml","Parents = root","OrderID asc");
//保存從 xml 中讀取出來(lái)的欄目的鏈接地址
string strLinkUrl;
//保存讀出來(lái)的欄目名稱
string strTitle;
//判斷是否有一級(jí)欄目
if(dv.Count > 0)
{
//先清空 label 的內(nèi)容,防止上次生成的內(nèi)容遺留下來(lái)
lblCode.Text = "";
//生成一級(jí)欄目表格-------------------------------
lblCode.Text = "<table width=100% border=0 align=center cellpadding=0 cellspacing=0 class=Cn12Black>";
lblCode.Text += "<tr><td width=100% height=3 class=bgGray></td></tr>";
lblCode.Text += "<tr><td class=bgGray>";
lblCode.Text += "<table height=30 border=0 cellpadding=3 cellspacing=0>";
lblCode.Text += "<tr>";
//循環(huán)讀出一級(jí)欄目
for(int i=0; i < dv.Count; i++)
{
strLinkUrl = dv[i]["LinkUrl"].ToString().Trim();
strTitle = dv[i]["Title"].ToString().Trim();
//如果是金喜正規(guī)買球,加粗及改變其單元格背景色,如果你的金喜正規(guī)買球不是 default.aspx,則修改為你的金喜正規(guī)買球,xml 中也要修改
if(strLinkUrl.Equals("default.aspx"))
{
lblCode.Text += "<td class=Cn12Gray>|</td>";
//改變金喜正規(guī)買球單元格背景的顏色,該顏色用 css中bgGray1 定義。
lblCode.Text += "<td class=bgGray1>";
//金喜正規(guī)買球指定的鏈接
lblCode.Text += "<a href=" + strLinkUrl + " class=navPad>";
//加粗金喜正規(guī)買球兩個(gè)字
lblCode.Text += "<strong>" + strTitle + "</strong>";
lblCode.Text += "</a>";
lblCode.Text += "</td>";
}
else
{
lblCode.Text += "<td class=Cn12Gray>|</td>";
lblCode.Text += "<td>";
lblCode.Text += "<a href=" + strLinkUrl + " class=navPad>";
lblCode.Text += strTitle;
lblCode.Text += "</a>";
lblCode.Text += "</td>";
}
}
lblCode.Text += "</tr></table>";
//顯示二級(jí)欄目
lblCode.Text += "</td></tr>";
//一級(jí)欄目 html 代碼到這里結(jié)束--------------------------
//顯示二級(jí)欄目,由于訪問金喜正規(guī)買球時(shí)二級(jí)欄目為空,所以此行高度調(diào)小,并且無(wú)內(nèi)容顯示
lblCode.Text += "<tr><td height=10 class=bgGray1>";
lblCode.Text += "</td></tr>";
lblCode.Text += "</table>";
//顯示當(dāng)前位置為金喜正規(guī)買球
lblPosition.Text = "";
lblPosition.Text += "<table width=100% border=0 cellspacing=0 cellpadding=6><tr><td class=Cn12BlackStrong>";
//如果在“當(dāng)前位置”前不想要圖片,把<img src=images/icon_alert.gif width=16 height=16 align=absbottom>去掉就行了
lblPosition.Text += "<img src=images/icon_alert.gif width=16 height=16 align=absbottom>當(dāng)前位置:<a href=default.aspx>金喜正規(guī)買球</a>";
lblPosition.Text += "</td></tr></table>";
}
方法2:重新顯示一級(jí)欄目
該方法是點(diǎn)擊除了“金喜正規(guī)買球”這一鏈接以外的一級(jí)欄目時(shí)調(diào)用的,實(shí)現(xiàn)的效果為重新顯示一級(jí)欄目,加粗當(dāng)前點(diǎn)擊的一級(jí)欄目名稱,并改變其單元格背景顏色。同時(shí)顯示屬于該一級(jí)欄目的二級(jí)欄目。方法命名為:showFirstMenuByFile(strNowViewFile),傳入的參數(shù)為當(dāng)前瀏覽的文件名稱。代碼如下:
public void showFirstMenuByFile(string strNowViewFile)
{
//讀取所有 Parents 為 root 的記錄
DataView dv = ReadXmlDataView("HeadMenu.xml","Parents = root","OrderID asc");
//保存欄目的鏈接地址
string strLinkUrl;
//保存欄目名稱
string strTitle;
if(dv.Count > 0)
{
lblCode.Text = "";
//生成表格
lblCode.Text = "<table width=100% border=0 align=center cellpadding=0 cellspacing=0 class=Cn12Black>";
lblCode.Text += "<tr><td width=100% height=3 class=bgGray></td></tr>";
lblCode.Text += "<tr><td class=bgGray>";
lblCode.Text += "<table height=30 border=0 cellpadding=3 cellspacing=0>";
lblCode.Text += "<tr>";
for(int i=0; i < dv.Count; i++)
{
strLinkUrl = dv[i]["LinkUrl"].ToString().Trim();
strTitle = dv[i]["Title"].ToString().Trim();
//如果讀出來(lái)的欄目名稱為當(dāng)前訪問的一級(jí)欄目的名稱,加粗并改變其單元格背景色
if(strLinkUrl.Equals(strNowViewFile))
{
lblCode.Text += "<td class=Cn12Gray>|</td>";
lblCode.Text += "<td class=bgGray1>";
lblCode.Text += "<a href=" + strLinkUrl + " class=navPad>";
lblCode.Text += "<strong>" + strTitle + "</strong>";
lblCode.Text += "</a>";
lblCode.Text += "</td>";
//改變當(dāng)前位置-------------------------------------
lblPosition.Text = "";
lblPosition.Text += "<table width=100% border=0 cellspacing=0 cellpadding=6><tr><td class=Cn12BlackStrong>";
lblPosition.Text += "<img src=images/icon_alert.gif width=16 height=16 align=absbottom>當(dāng)前位置:<a href=default.aspx>金喜正規(guī)買球</a>";
lblPosition.Text += " >> <a href=" + strLinkUrl + ">" + strTitle + "</a>";
lblPosition.Text += "</td></tr></table>";
}
else
{
lblCode.Text += "<td class=Cn12Gray>|</td>";
lblCode.Text += "<td>";
lblCode.Text += "<a href=" + strLinkUrl + " class=navPad>";
lblCode.Text += strTitle;
lblCode.Text += "</a>";
lblCode.Text += "</td>";
}
}
lblCode.Text += "</tr></table>";
//一級(jí)欄目 html 代碼到這里結(jié)束
lblCode.Text += "</td></tr>";
}
}
方法3:顯示屬于當(dāng)前訪問的一級(jí)欄目的二級(jí)欄目
該方法只顯示一級(jí)欄目下的二級(jí)欄目,并不需要實(shí)現(xiàn)加粗和改變單元格背景這效果。該方法命名為:showSecondMenu(strNowViewFile)。代碼如下:
public void showSecondMenu(string strNowViewFile)
{
//根據(jù)傳入的當(dāng)前該問的文件查找當(dāng)前訪問的欄目名稱
DataView dvNowMenu = ReadXmlDataView("HeadMenu.xml","LinkUrl = " + strNowViewFile + "","OrderID asc");
//當(dāng)前訪問的欄目名稱
string strTitle = dvNowMenu[0]["Title"].ToString();
//讀取所有屬于該欄目的二級(jí)欄
DataView dvSecond = ReadXmlDataView("HeadMenu.xml","Parents = " + strTitle + "","OrderID asc");
if(dvSecond.Count > 0)
{
//輸出二級(jí)欄目
lblCode.Text += "<tr>";
lblCode.Text += "<td height=30 class=bgGray1>";
for(int i=0; i < dvSecond.Count; i++)
{
//如果讀出來(lái)的那條記錄的鏈接地址是當(dāng)前訪問的文件,加粗當(dāng)前訪問的欄目名稱并在前面加上·符號(hào)
if(dvSecond[i]["LinkUrl"].ToString().Trim().Equals(strNowViewFile))
{
lblCode.Text += "&nbsp; ·<a href=" + dvSecond[i]["LinkUrl"].ToString().Trim() + ">";
lblCode.Text += "<strong>" + dvSecond[i]["Title"].ToString().Trim() + "</strong>";
lblCode.Text += "</a>";
//改變當(dāng)前位置值,重新顯示一級(jí)欄目的方法已經(jīng)顯示了當(dāng)前的一級(jí)欄目位置,這里加上當(dāng)前所在的二級(jí)欄目的位置
lblPosition.Text += " >> <a href=" + dvSecond[i]["LinkUrl"].ToString().Trim() + ">" + strTitle + "</a>";
//到這里當(dāng)前位置的表格顯示已完成,剛好和重新顯示一級(jí)欄目方法里的當(dāng)前位置的表格代碼接起來(lái)
lblPosition.Text += "</span></td></tr></table>";
}
else
{
lblCode.Text += " <a href=" + dvSecond[i]["LinkUrl"].ToString().Trim() + ">";
lblCode.Text += dvSecond[i]["Title"].ToString().Trim();
lblCode.Text += "</a>";
}
}
lblCode.Text += "</td>";
lblCode.Text += "</tr>";
lblCode.Text += "</table>";
}
}
方法4:訪問二級(jí)欄目的時(shí)候重新顯示一級(jí)欄目
該方法是訪問二級(jí)欄目時(shí)調(diào)用的,訪問二級(jí)欄目的時(shí)候,其父級(jí)欄目需要加粗并改變單元格背景。該方法命令為:showFirstMenuBySecondFile(strNowViewFile)。由于該方法與 showFirstMenuByFile()方法大同小異,這里就不詳細(xì)介紹了。具體可以查看源代碼。
方法5:訪問二級(jí)欄目的時(shí)候顯示二級(jí)欄目
該方法是訪問二級(jí)欄目的時(shí)候調(diào)用的,用來(lái)顯示所有二級(jí)欄目,加粗當(dāng)前訪問的二級(jí)欄目,并改變當(dāng)前位置,方法命名為:showSecondMenuByGrade(strNowViewFile)。該方法與 showSecondMenu()方法也是大同小異,所以也不詳細(xì)介紹了。
接下來(lái)只要在 Page_Load 事件中通過(guò)顯示或隱藏一級(jí)欄目和二級(jí)欄目就能達(dá)到圖上的效果。Page_Load 事件的代碼如下:
private void Page_Load(object sender, System.EventArgs e)
{
// 在此處放置用戶代碼以初始化頁(yè)面
if(!Page.IsPostBack)
{
//先根據(jù)地址欄的地址獲取訪問的文件,如:default.aspx
//獲得url的相對(duì)路徑
string strRequestUrl = Request.Url.AbsolutePath.ToString().Trim();
//獲得當(dāng)前訪問的文件名
string strNowViewFile = strRequestUrl.Substring((strRequestUrl.LastIndexOf(@"/") + 1)).Trim();
//根據(jù)取得的訪問文件查找其對(duì)應(yīng)的記錄,以判斷當(dāng)前訪問一級(jí)欄目還是二級(jí)欄目
//讀取當(dāng)前訪問文件名對(duì)應(yīng)的那條信息
DataView dv = ReadXmlDataView("HeadMenu.xml","LinkUrl = " + strNowViewFile + "","OrderID asc");
//當(dāng)前訪問欄目的上級(jí)欄目名稱
string strParent = dv[0]["Parents"].ToString().Trim();
//如果訪問的是金喜正規(guī)買球
if(strNowViewFile.Equals("default.aspx") || strNowViewFile == null)
{
//顯示所有一級(jí)欄目
showFirstMenu();
}
//如果訪問的是一級(jí)欄目,并且不是金喜正規(guī)買球
else if(strParent.Equals("root"))
{
//重新顯示一級(jí)欄目
showFirstMenuByFile(strNowViewFile);
//讀取所有屬于該一級(jí)欄目的二級(jí)欄目
showSecondMenu(strNowViewFile);
}
//否則當(dāng)前訪問的就是二級(jí)欄目
else
{
//顯示一級(jí)欄目,同時(shí)加粗二級(jí)欄目所屬的一級(jí)欄目,并改變?cè)撘患?jí)欄目的單元格背景
showFirstMenuBySecondFile(strNowViewFile);
//顯示二級(jí)欄目,加粗并在當(dāng)前訪問的二級(jí)欄目名稱前加。符號(hào)
showSecondMenuByGrade(strNowViewFile);
}
}
}
以上就是頂部導(dǎo)航自定義控件的核心部份了,看完了后是不是覺得很簡(jiǎn)單?由于寫的時(shí)候是為了應(yīng)付項(xiàng)目的需要,因此匆匆忙忙就完工了,大家如果發(fā)現(xiàn)什么BUG,或是有什么好的意見可以聯(lián)系我。控件的具體用法請(qǐng)看壓縮包內(nèi)的說(shuō)明。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載