Der Zweck dieses Artikels ist es, ein glatt aussehendes und einfach zu verwendendes Menü für eine ASP.NET -fähige Website zu erstellen. Um dies zu erreichen, verwenden wir die Standardfunktionalität der Websteuerung des ASP.NET -Menüs und verbessern Sie den Look nur mithilfe von Cascading Style Sheets (CSS).
Für diejenigen unter Ihnen, die mit CSS vertraut sind, wird der Titel dieses Artikels sicherlich eine Glocke läuten. Das CSS, das verwendet wird, um das Erscheinungsbild des ASP.NE -Menüssteuerung zu verbessern, wird in einem weithin bekannten Artikel auf einer Liste mit dem Titel "Schiebetüren von CSS" verringert.
Das CSS, mit dem das Erscheinungsbild des Menüs verbessert wird, wird in dem Artikel auf einer Liste auseinander erklärt. Gutschrift, wenn Kredit fällig ist. Vielen Dank an Douglas Bowman, der uns das CSS geliefert hat. Lesen Sie zuerst seinen Artikel, wenn Sie damit nicht vertraut sind.
Der Schwerpunkt dieses Artikels liegt auf der Simulation eines solchen Menüs in einer ASP.NET -Umgebung. Lass uns anfangen ...
Lassen Sie uns Visual Studio 2008 aufstellen und ein neues Projekt mit der ASP.NET -Webanwendungs -Projektvorlage erstellen. Diese Vorlage fügt automatisch ein Standard -Webformular hinzu, das entsprechend "default.aspx" bezeichnet wird. Öffnen Sie es im Editor und fügen Sie die Menüsteuerung in der Toolbox hinzu, die Sie auf der Registerkarte Navigation finden können. Wenn Sie die Website jetzt ausführen, starren Sie auf eine leere Seite. Damit das Menü alles anzeigen kann, muss es zuerst an einige Daten gebunden sein.
Der einfachste Weg, um Daten für die Verwendung der Menüsteuerung zu definieren und die Besucher zu ermöglichen, durch die Website zu navigieren, besteht darin, sie an eine Site -Karte zu binden. Fügen Sie dem Projekt mit dem vorgeschlagenen Namen "web.Sitemap" ein neues Site -Karte -Element hinzu. Die Site -Karte ist eine XML -Datei, die die Seiten der Site auf hierarchische Weise organisiert. Ein zusätzlicher Vorteil ist, dass es automatisch von der SitemapdataSource -Steuerung verwiesen wird.
Fügen Sie als nächstes ein paar Seiten der Sitemap hinzu, wie in der folgenden Auflistung angezeigt wird.
Listing 1 - Web.Sitemap
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< siteMap xmlns = " http://schemas.microsoft.com/AspNet/SiteMap-File-1.0 " >
< siteMapNode url = " " title = " " description = " " >
< siteMapNode url = " Default.aspx " title = " Home " description = " Take me back to the dasboard " />
< siteMapNode url = " Products.aspx " title = " Products " description = " Browse our catalog " />
< siteMapNode url = " Download.aspx " title = " Download " description = " Download neat stuff " />
< siteMapNode url = " Forum.aspx " title = " Forum " description = " Ask questions on our forum " />
< siteMapNode url = " Contact.aspx " title = " Contact " description = " Contact us " />
</ siteMapNode >
</ siteMap >Fügen Sie nun der Seite eine SitemapdataSource -Steuerung hinzu und setzen Sie die DataSourceid -Eigenschaft der Menüsteuerung auf die ID der Datenquelle. Setzen Sie auch die Ausrichtung Eigenschaft des Menüsteuerers auf horizontal, sobald sie standardmäßig vertikal ist. Last but not least setzen Sie die Showstart -Node -Eigenschaft der SitemapdataSource auf false. Wenn Sie dies nicht tun, wird nur der Stammknoten angezeigt und wir möchten diesen Basisknoten nicht in das Menü aufnehmen. Ihr Code sollte nun dem in Listing 2 angezeigten Code ähneln.
Listing 2 - Standard.aspx
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
> </ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>Wenn Sie die Seite jetzt in einem Browser anzeigen, sollten Sie ein funktionales, dennoch langweiliges Menü sehen.
Abbildung 1 - Einfaches horizontales Menü

Bevor wir mit der Anwendung von CSS auf das Menü beginnen können, muss zuerst ein weiteres Problem behandelt werden. Wenn Sie sich den resultierenden HTML -Code ansehen, der beim Anfordern der Seite "Standard.aspx" generiert wird, werden Sie feststellen, dass die Menüsteuerung nicht den flexibelsten HTML -Code generiert. Standardmäßig wickelt es jeden Menüelement in einer Tabelle ein. Dies eignet sich nicht für die leicht angewendete Anwendung von CSS. Es wäre besser, wenn die Menüsteuerung eine unbestrahlende Liste erzeugt, die alle Menüelemente enthält.
Glücklicherweise kann der generierte HTML mithilfe von Kontrolladaptern eingestellt werden. Mit Kontrolladaptern können Sie die von Ihnen bevorzugte HTML rendern. Zum Glück sind solche Kontrolladapter auf Codeplex leicht verfügbar. Das CSS Friendly Control Adapters Kit bietet vorgefertigte Steuerungsadapter, einschließlich eines für das ASP.NET-Menüsteuerung.
Um die CSS -freundlichen Kontrolladapter zu verwenden, folgen Sie folgenden Schritten:
Es ist notwendig, den Quellcode zu verwenden und die CSSFriendly.dll -Assemblierung selbst zu kompilieren, da wir einige der von den Adaptern später in diesem Artikel verwendeten CSS optimieren müssen.
Beim Hinzufügen des CSSSFriendly -Projekts zu Ihrer Lösung wird der Visual Studio Conversion Assistent aufgebaut. Führen Sie einfach die Konvertierung aus, alles sollte reibungslos verlaufen. Wenn die Konvertierung abgeschlossen ist, ist alles, was noch übrig bleibt, einen Verweis auf das CSSFriendly -Projekt aus dem ASP.NET -Website -Projekt hinzuzufügen.
Führen Sie einfach die Website aus und sehen Sie sich jetzt den generierten HTML -Code an.
Listing 3 - CSS -freundlicher HTML -Code
< div class =" AspNet-Menu-Horizontal " id =" Menu1 " >
< ul class =" AspNet-Menu " >
< li class =" AspNet-Menu-Leaf AspNet-Menu-Selected " >
< a
href =" /Default.aspx "
class =" AspNet-Menu-Link AspNet-Menu-Selected "
title =" Take me back to the dasboard "
> Home </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Products.aspx "
class =" AspNet-Menu-Link "
title =" Browse our catalog "
> Products </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Download.aspx "
class =" AspNet-Menu-Link "
title =" Download neat stuff "
> Download </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Forum.aspx "
class =" AspNet-Menu-Link "
title =" Ask questions on our forum "
> Forum </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a href =" /Contact.aspx " class =" AspNet-Menu-Link " title =" Contact us "
> Contact </ a
>
</ li >
</ ul >
</ div >Die Dinge sehen jetzt nach.
Bemerkung : Mit der CSSFriendlyadapter.Browser -Datei können Sie angeben, welche CSS -freundlichen Steueradapter verwendet werden sollen. Ich mache ein Habbit, um alle Adapter zu kommentieren, außer denen, die ich verwenden möchte. Auf diese Weise werden keine anderen Steuerelemente "angepasst" und generieren weiterhin die Standard -HTML.
Wie Sie aus dem Code sehen können, der in der Auflistung über dem Adapter für die Menüsteuerung angezeigt wird, injiziert automatisch die erforderlichen CSS -Klassen für die Tags <ul> , <li> und <a> . Dies erspart uns die Mühe, diese zu definieren.
Es ist auch weit verbreitet, dass eine einzelne Seite mehr als eine einzelne Adaptersteuerung wie ein Menü enthält. Wenn Sie für jede Kontrolle ein ausgeprägtes Erscheinungsbild wünschen, stellen Sie die CSSelectorClass für die angepasste Kontrolle ein. Zum Beispiel können Sie den Wert der CSSELECTORCASSCLASS -Eigenschaft wie folgt festlegen:
Auflistung 4 - CSSELECTORCASSCLASS -Eigentum
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
> </ asp:Menu > Das Ergebnis ist, dass der durch die angepasste Steuerung generierte HTML -Code in einer neuen Ebene ( <div> ) enthalten ist.
Listing 5 - Wickeln Sie den generierten HTML -Code ein
< div class =" PrettyMenu " id =" Menu1 " >
<!-- Other HTML code -->
</ div >Beachten Sie, dass diese Eigenschaft spezifisch für die CSS -freundlichen Adapter ist. Es handelt sich um ein benutzerdefiniertes (Expecto) Attribut, das Sie für die von dieser Bibliothek unterstützten Steuerelemente festlegen können. Sie benötigen weitere Informationen über die Funktionsweise der freundlichen Adapter. Bitte konsultieren Sie die folgenden Links:
Mit der CSSelectorClass, die eine separate Ebene ( <div> ) rund um das Menü und die automatisch injizierten CSS -Klassen erzeugt, sind wir endlich bereit, das Menü zu stylen.
Das verwendete CSS entspricht dem der A -List -Apart -Artikel. Wie bereits erwähnt, liegt der Fokus dieses Artikels auf der Struktur des CSS, sondern auf die Anwendung des Menüsteuerung von ASP.NET, um ein ordentlich aussehendes tabelläres Menü zu erhalten. Das fertige Ergebnis ist in Abbildung 2 zu sehen.
Abbildung 2 - Das fertige Ergebnis

Auf der Download -Seite finden Sie den Quellcode für diesen Artikel. Es enthält das Stilblatt und die erforderlichen Bilder. Führen Sie einfach die folgenden Schritte aus, um das fertige Ergebnis nachzubilden:
<Pages> -Knoten auf Standard. (Siehe Listing 6)Listing 6 - Web.Config -Auszug
< system .web>
<!-- ... -->
< pages theme = " Default " >
<!-- ... -->
</ pages >
<!-- ... -->
</ system .web>Das in meiner Lösung verwendete CSS entspricht dem des Artikels auf einer Liste, aber es gibt einige Änderungen. Vor allem die Änderungen korrelieren mit der CSS -Struktur, die von den CSS -freundlichen Adaptern angewendet wird.
Um das CSS anzuwenden, muss die richtige Struktur verwendet werden. Beim Stylen einer Kontrolle, deren HTML durch einen freundlichen Adapter angepasst wird, finde ich es praktisch, Diagramme zu verwenden, die im Whitepaper erwähnt werden. Diese Diagramme zeigen Ihnen deutlich, wie das CSS strukturiert ist.
Hier finden Sie das Diagramm für die Menüsteuerung.
Eine Frage, die ich häufig in vielen Foren aufgenommen habe, ist die Implementierung eines horizontalen Untermenüs, das sich ändert, wenn der Benutzer im Menü oberster Ebene eine andere Registerkarte auswählt. Um dies zu erstellen, müssen wir zunächst unsere Site -Karte anpassen.
Listing 7 zeigt die angepasste Site -Karte.
Listing 7 - Web.Sitemap mit "Sub -Menüelemente"
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< siteMap xmlns = " http://schemas.microsoft.com/AspNet/SiteMap-File-1.0 " >
< siteMapNode url = " " title = " " description = " " >
< siteMapNode url = " Default.aspx " title = " Home " description = " Take me back to the dasboard " >
< siteMapNode url = " About.aspx " title = " About us " description = " " />
< siteMapNode url = " Foo.aspx " title = " Foo " description = " " />
< siteMapNode url = " Bar.aspx " title = " Bar " description = " " />
</ siteMapNode >
<!-- ... -->
</ siteMap >Für den Sake -List von Brevity 7 wird nur die Sub -Menüelemente (Knoten) für den Heimknoten angezeigt. Schauen Sie sich das Web.Sitemap im Quellcode für die vollständige Version an. Wenn Sie nun die Website mit dieser Site -Karte durchsuchen, sehen Sie den in Abbildung 3 gezeigten Effekt.
Abbildung 3 - Untermenüelemente der Untermenschen

Um diesen Effekt zu deaktivieren, setzen Sie die MaximumDynamicDisplay -Lesplay -Eigenschaft der Menüsteuerung auf Null, wie in Listing 8 gezeigt.
Listing 8 - MaximumDynamicdisplaylevels Eigenschaft
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
> </ asp:Menu >Fügen Sie als nächstes ein zweites Menü und SitemapdataSource -Steuerung hinzu und setzen Sie ihre Eigenschaften wie in Listing 9 gezeigt.
Listing 9 - Sub -Menüsteuerung
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
>
</ asp:Menu >
< asp:Menu
ID =" Menu2 "
runat =" server "
DataSourceID =" SitemapDataSource2 "
Orientation =" Horizontal "
CssSelectorClass =" PrettySubMenu "
>
</ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>
< asp:SiteMapDataSource
ID =" SiteMapDataSource2 "
runat =" server "
StartingNodeOffset =" 1 "
ShowStartingNode =" False "
/>Wir geben im Grunde das zweite Menü an, dass es die zweite Stufe der in der Site -Karte gefundenen Knoten anzeigen soll und dass der Startknoten nicht angezeigt werden sollte, der der Registerkarte "Ausgewählte Registerkarte" des ersten Menüs entspricht.
Auch die CSSelectorClass für das zweite Menü ist auf PrettySubMenu eingestellt. Das CSS für dieses Menü entspricht dem ersten Menü. Laden Sie den Quellcode herunter, wenn Sie ihn überprüfen möchten. Wenn Sie jetzt die Website ausführen, erhalten Sie dieses schicke Ergebnis.
Abbildung 4 - Styled Sub -Menüelemente

Ein letztes Problem muss gelöst werden. Um dieses Problem zu veranschaulichen, muss das Projekt neu organisiert werden.
Lassen Sie uns zunächst dem Projekt namens Site.master eine Master -Seite hinzufügen. Verschieben Sie den Code, die Menüs und Datenquellen, von der Seite Standard.aspx auf die Masterseite und platzieren Sie ihn kurz vor dem ersten Inhaltshalter in der Karosserie. Anschließend können Sie die Seite "Standard.aspx" sicher löschen.
Fügen wir nun dem Projekt einige Elemente des Webinhaltsformulars hinzu. Fügen Sie Web -Inhaltsformulare hinzu, die den Elementen des ersten Knotens der Site -Karte und ihrer Subknoten entsprechen, nämlich:
Wählen Sie unbedingt Site.master als Masterseite für jede dieser Webinhaltsformulare. Die anderen im Web.Sitemap genannten Seiten sind nur für veranschaulichende Zwecke da.
Starten Sie die Website erneut und navigieren Sie zur FOO -Seite. Dies wird das Problem zeigen.
Abbildung 5 - Auswahlproblem

Da wir in der Site -Karte nach unterer Ebene navigiert haben. Das Menü mit oberster Ebene weiß nicht, welches Menüelement er als ausgewählte markiert werden soll. Wir müssen im Code der Masterseite ein paar Codierung durchführen, um dies zu lösen.
Auflistung 10 zeigt den erforderlichen Code -Bissen.
Auflistung 10 - Auswählen des korrekten Menüpunkts der obersten Ebene
namespace MenuWebApplication
{
public partial class Site : System . Web . UI . MasterPage
{
private static string ExtractBaseUrl ( string url )
{
return url . Contains ( "?" ) ? url . Remove ( url . IndexOf ( '?' ) ) : url ;
}
protected void Page_Load ( object sender , EventArgs e )
{
Menu1 . DataBind ( ) ;
// Which node in the site map is currently selected?
SiteMapNode currentNode = SiteMap . CurrentNode ;
if ( currentNode != null )
{
// Obtain the Url of the currently selected node's parent node.
string parentUrl = String . Empty ;
SiteMapNode parentNode = currentNode . ParentNode ;
if ( parentNode != null )
{
parentUrl = ExtractBaseUrl ( parentNode . Url ) ;
}
// Obtain the Url of the currently selected node.
string currentUrl = ExtractBaseUrl ( currentNode . Url ) ;
// Iterate the top level menu tier.
foreach ( MenuItem menuItem in Menu1 . Items )
{
// Compare the menu item's Url against the currently
// selected node's Url or the Url of its parent.
string menuItemUrl = ExtractBaseUrl ( menuItem . NavigateUrl ) ;
if ( ( currentUrl == menuItemUrl ) || ( parentUrl == menuItemUrl ) )
{
// If either matches then mark the top level menu item as selected.
Menu1 . Items [ Menu1 . Items . IndexOf ( menuItem ) ] . Selected = true ;
break ;
}
}
}
}
}
}Jetzt können Sie eine der Sub -Menüelemente auswählen. Der entsprechende Menüpunkt der obersten Ebene bleibt ausgewählt, um dem Besucher einen visuellen Hinweis darauf zu geben, wo er sich derzeit auf der Website befindet.
Abbildung 6 - Auswahlproblem behoben

Es ist einiges an Arbeit, ein ausgefallenes tabellarisches Menü mit einem kontextsensitiven horizontalen Untermenü zu erstellen, aber am Ende enden Sie ein glatt aussehendes und benutzerfreundliches Menü.
Ich schlage vor, dass Sie ein solches Menü in einer Benutzersteuerung implementieren und diese Benutzersteuerung auf der Masterseite Ihrer Website aufnehmen. In den meisten Fällen wird ein solches Menü auf der gesamten Website verwendet.