Använda Repeater istället för Menu komponenten

Jag har börjat använda Web.sitemap flitigare i mina applikationer. asp:Menu komponenten är ju smidig eftersom den är så lätt att binda till en SiteMapDataSource och menyn ritas fram automatiskt.

Men jag stötte dock på en del problem som jag inte vet hur man kan lösa. För det första genererar den onödigt mycket kod med mängder av nästlade tabeller och det är väldigt svårt att lista ut hur man ska få den att uppföra sig precis som man vill.

Sen ville jag ha streckade linjer som separatorer och använde StaticBottomSeparatorImageUrl för att ange min bild. Kunde dock inte komma på hur man kan göra för att bara ha dem imellan menylänkarna. Inte före eller efter med andra ord.

Efter ett stunds sökning på nätet gav jag upp. Hittade istället en djupgående artikelserie på www.devx.com där nio problem med sajt navigation tas upp. Där hittade jag ett tips om hur man kan binda ihop en Repeater till sin SiteMapDataSource istället för Menu kontrollen. Men hjälp av Repeatern kunde jag placera separator koden där jag ville samt att få hela menyn att renderera snyggare utan massa överflödiga tabeller.

Repeatern

<table width="100%" cellpadding="0" cellspacing="5px">
<tr>
<td class="menuBack">

<asp:Repeater ID="repeaterMenu" runat="server" DataSourceID="smds" OnItemDataBound="repeaterMenu_ItemDataBound">
<ItemTemplate>
<asp:PlaceHolder ID="phMenuSeparator" runat="server" />
<a class="menu" href='<%# String.Format( ((SiteMapNode)Container.DataItem).Url)%>' target='_top'><%# String.Format( ((SiteMapNode)Container.DataItem).Title)%></a>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</table>

<asp:SiteMapDataSource ID="smds" ShowStartingNode="False" runat="server" />

Koden bakom

//Räknare för att hålla reda på vilken länk man är på i menyn
int intCounter = 0;

public void repeaterMenu_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
try
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{

//Lägg bara till separator ifall efter vi passerat första meny objektet
if (intCounter > 0)
{
PlaceHolder phMenuSeparator = (PlaceHolder)e.Item.FindControl("phMenuSeparator");
phMenuSeparator.Controls.Add(new LiteralControl(" &lt;div class='menuSeparator' &gt;&lt;/div&gt;"));
}
intCounter++;
}
}
catch (Exception objException)
{
Trace.Write("repeaterMenu_OnDataBinding() Fel!", objException.Message);
}
}

Css

.menuBack
{
border:1px solid #cccccc;
background-image: url('../images/menu_back.gif') ;
background-repeat:repeat-x;
background-position:top;
height:1.6em;

}

.menuBackSelected
{

background-image: url('../images/menu_back_selected.gif') ;
background-repeat:repeat-x;
background-position:top;
display:block;
float:left;
height:110%;
margin:0;
color:#000;
}

.menuSeparator
{
background-image: url('../images/menu_separator.gif') ;
background-repeat:repeat-y;
display:block;
float:left;
margin:0;
height:110%;
width:1px;

}


a.menu
{
padding: 0.2em 10px 0.2em 10px;
font-weight:bold;
text-decoration: none;
color: #fff;
display:block;
float:left;
}

a.menu:link
{
color: #fff;
}

a.menu:visited
{
color: #fff;
}

a.menu:hover
{

color: #fff;
text-decoration: underline;}

a.menu:active
{
color: #fff;
text-decoration: underline;}

a.menuselected
{
padding: 0.2em 10px 0.2em 10px;
font-weight:bold;
color: #000;
text-decoration: none;
display:block;
float:left;
}

a.menuselected:link
{
color: #000;
}

a.menuselected:visited
{
color: #000;
}

a.menuselected:hover
{
text-decoration: underline;}

a.menuselected:active
{
text-decoration: underline;}