locked
Can you set the css adapters to that each <li> node displays a unique id? RRS feed

  • Question

  • User-943454799 posted

    Can you set the css adapters to that each <li> node displays a unique id?

    Wednesday, March 12, 2008 8:51 PM

Answers

  • User-656867934 posted

    Make sure you are working with the latest version of the source code, then try this: Locate the BuildItem & BuildItems functions in the MenuAdapter.cs file, and make the changes indicated below:

     

    // Locate the foreach loop in BuildItems, and modify it to look like this:
    int i = 0;
    foreach (MenuItem item in items)
    {
    	BuildItem(item, writer, i++);
    }
    
    And for BuildItem():
     
    // Modify the next line, add the , int i
    private void BuildItem(MenuItem item, HtmlTextWriter writer, int i)
    {
        Menu menu = Control as Menu;
        if ((menu != null) && (item != null) && (writer != null))
        {
    	    writer.WriteLine();
    	    writer.WriteBeginTag("li");
                // You want to add this next line to your code
                writer.WriteAttribute("id", String.Format("menuLevel_{0}_{1}", item.Depth, i.ToString()));
     

    Recompile the DLL, drop it in your bin directory or put it in your GAC, and your done. Here is the code in its' entirety:

    1    using System;
    2    using System.Collections;
    3    using System.Reflection;
    4    using System.IO;
    5    using System.Web;
    6    using System.Web.Configuration;
    7    using System.Web.UI;
    8    using System.Web.UI.WebControls;
    9    using System.Web.UI.HtmlControls;
    10   
    11   namespace CSSFriendly
    12   {
    13   	public class MenuAdapter : System.Web.UI.WebControls.Adapters.MenuAdapter
    14   	{
    15   		private WebControlAdapterExtender _extender = null;
    16   		private WebControlAdapterExtender Extender
    17   		{
    18   			get
    19   			{
    20   				if (((_extender == null) && (Control != null)) ||
    21   					((_extender != null) && (Control != _extender.AdaptedControl)))
    22   				{
    23   					_extender = new WebControlAdapterExtender(Control);
    24   				}
    25   
    26   				System.Diagnostics.Debug.Assert(_extender != null, "CSS Friendly adapters internal error", "Null extender instance");
    27   				return _extender;
    28   			}
    29   		}
    30   
    31   		protected override void OnInit(EventArgs e)
    32   		{
    33   			base.OnInit(e);
    34   
    35   			if (Extender.AdapterEnabled)
    36   			{
    37   				RegisterScripts();
    38   			}
    39   		}
    40   
    41   		private void RegisterScripts()
    42   		{
    43   			Extender.RegisterScripts();
    44   
    45   			/* 
    46   			 * Modified for support of compiled CSSFriendly assembly
    47   			 * 
    48   			 * We will first search for embedded JavaScript files. If they are not
    49   			 * found, we default to the standard approach.
    50   			 */
    51   
    52   			Type type = this.GetType();
    53   
    54   			// MenuAdapter.js
    55   			Helpers.RegisterClientScript("CSSFriendly.JavaScript.MenuAdapter.js", type, this.Page);
    56   
    57   			// Menu.css
    58   			Helpers.RegisterEmbeddedCSS("CSSFriendly.CSS.Menu.css", type, this.Page);
    59   
    60   			// Only send IEMenu6.css if it's IE version <7
    61   			if (this.Browser.Browser.ToUpper().IndexOf("IE") >= 0
    62   				&& this.Browser.MajorVersion < 7)
    63   			{
    64   				Helpers.RegisterEmbeddedCSS("CSSFriendly.CSS.BrowserSpecific.IEMenu6.css", type, this.Page);
    65   			}
    66   		}
    67   
    68   		protected override void RenderBeginTag(HtmlTextWriter writer)
    69   		{
    70   			if (Extender.AdapterEnabled)
    71   			{
    72   				Extender.RenderBeginTag(writer, "AspNet-Menu-" + Control.Orientation.ToString());
    73   			}
    74   			else
    75   			{
    76   				base.RenderBeginTag(writer);
    77   			}
    78   		}
    79   
    80   		protected override void RenderEndTag(HtmlTextWriter writer)
    81   		{
    82   			if (Extender.AdapterEnabled)
    83   			{
    84   				Extender.RenderEndTag(writer);
    85   			}
    86   			else
    87   			{
    88   				base.RenderEndTag(writer);
    89   			}
    90   		}
    91   
    92   		protected override void RenderContents(HtmlTextWriter writer)
    93   		{
    94   			if (Extender.AdapterEnabled)
    95   			{
    96   				writer.Indent++;
    97   				BuildItems(Control.Items, true, writer);
    98   				writer.Indent--;
    99   				writer.WriteLine();
    100  			}
    101  			else
    102  			{
    103  				base.RenderContents(writer);
    104  			}
    105  		}
    106  
    107  		private void BuildItems(MenuItemCollection items, bool isRoot, HtmlTextWriter writer)
    108  		{
    109  			if (items.Count > 0)
    110  			{
    111  				writer.WriteLine();
    112  
    113  				writer.WriteBeginTag("ul");
    114  				if (isRoot)
    115  				{
    116  					writer.WriteAttribute("class", "AspNet-Menu");
    117  				}
    118  				writer.Write(HtmlTextWriter.TagRightChar);
    119  				writer.Indent++;
    120  
    121                  int i = 0;
    122                  foreach (MenuItem item in items)
    123                  {
    124  	                BuildItem(item, writer, i++);
    125                  }
    126  
    127  				writer.Indent--;
    128  				writer.WriteLine();
    129  				writer.WriteEndTag("ul");
    130  			}
    131  		}
    132  
    133          private void BuildItem(MenuItem item, HtmlTextWriter writer, int i)
    134          {
    135              Menu menu = Control as Menu;
    136              if ((menu != null) && (item != null) && (writer != null))
    137              {
    138                  writer.WriteLine();
    139                  writer.WriteBeginTag("li");
    140                  writer.WriteAttribute("id", String.Format("menuLevel_{0}_{1}", item.Depth, i.ToString()));
    141  
    142  				string theClass = (item.ChildItems.Count > 0) ? "AspNet-Menu-WithChildren" : "AspNet-Menu-Leaf";
    143  				string selectedStatusClass = GetSelectStatusClass(item);
    144  				if (!String.IsNullOrEmpty(selectedStatusClass))
    145  				{
    146  					theClass += " " + selectedStatusClass;
    147  				}
    148  				writer.WriteAttribute("class", theClass);
    149  
    150  				writer.Write(HtmlTextWriter.TagRightChar);
    151  				writer.Indent++;
    152  				writer.WriteLine();
    153  
    154  				if (((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null)) ||
    155  					((item.Depth >= menu.StaticDisplayLevels) && (menu.DynamicItemTemplate != null)))
    156  				{
    157  					writer.WriteBeginTag("div");
    158  					writer.WriteAttribute("class", GetItemClass(menu, item));
    159  					writer.Write(HtmlTextWriter.TagRightChar);
    160  					writer.Indent++;
    161  					writer.WriteLine();
    162  
    163  					MenuItemTemplateContainer container = new MenuItemTemplateContainer(menu.Items.IndexOf(item), item);
    164  					if ((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null))
    165  					{
    166  						menu.StaticItemTemplate.InstantiateIn(container);
    167  					}
    168  					else
    169  					{
    170  						menu.DynamicItemTemplate.InstantiateIn(container);
    171  					}
    172  					container.DataBind();
    173  					container.RenderControl(writer);
    174  
    175  					writer.Indent--;
    176  					writer.WriteLine();
    177  					writer.WriteEndTag("div");
    178  				}
    179  				else
    180  				{
    181  					if (IsLink(item))
    182  					{
    183  						writer.WriteBeginTag("a");
    184  						if (!String.IsNullOrEmpty(item.NavigateUrl))
    185  						{
    186  							writer.WriteAttribute("href", Page.Server.HtmlEncode(menu.ResolveClientUrl(item.NavigateUrl)));
    187  						}
    188  						else
    189  						{
    190  							writer.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(menu, "b" + item.ValuePath.Replace(menu.PathSeparator.ToString(), "\\"), true));
    191  						}
    192  
    193  						writer.WriteAttribute("class", GetItemClass(menu, item));
    194  						WebControlAdapterExtender.WriteTargetAttribute(writer, item.Target);
    195  
    196  						if (!String.IsNullOrEmpty(item.ToolTip))
    197  						{
    198  							writer.WriteAttribute("title", item.ToolTip);
    199  						}
    200  						else if (!String.IsNullOrEmpty(menu.ToolTip))
    201  						{
    202  							writer.WriteAttribute("title", menu.ToolTip);
    203  						}
    204  						writer.Write(HtmlTextWriter.TagRightChar);
    205  						writer.Indent++;
    206  						writer.WriteLine();
    207  					}
    208  					else
    209  					{
    210  						writer.WriteBeginTag("span");
    211  						writer.WriteAttribute("class", GetItemClass(menu, item));
    212  						writer.Write(HtmlTextWriter.TagRightChar);
    213  						writer.Indent++;
    214  						writer.WriteLine();
    215  					}
    216  
    217  					if (!String.IsNullOrEmpty(item.ImageUrl))
    218  					{
    219  						writer.WriteBeginTag("img");
    220  						writer.WriteAttribute("src", menu.ResolveClientUrl(item.ImageUrl));
    221  						writer.WriteAttribute("alt", !String.IsNullOrEmpty(item.ToolTip) ? item.ToolTip : (!String.IsNullOrEmpty(menu.ToolTip) ? menu.ToolTip : item.Text));
    222  						writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    223  					}
    224  
    225  					writer.Write(item.Text);
    226  
    227  					if (IsLink(item))
    228  					{
    229  						writer.Indent--;
    230  						writer.WriteEndTag("a");
    231  					}
    232  					else
    233  					{
    234  						writer.Indent--;
    235  						writer.WriteEndTag("span");
    236  					}
    237  
    238  				}
    239  
    240  				if ((item.ChildItems != null) && (item.ChildItems.Count > 0))
    241  				{
    242  					BuildItems(item.ChildItems, false, writer);
    243  				}
    244  
    245  				writer.Indent--;
    246  				writer.WriteLine();
    247  				writer.WriteEndTag("li");
    248  			}
    249  		}
    250  
    251  		private bool IsLink(MenuItem item)
    252  		{
    253  			return (item != null) && item.Enabled && ((!String.IsNullOrEmpty(item.NavigateUrl)) || item.Selectable);
    254  		}
    255  
    256  		private string GetItemClass(Menu menu, MenuItem item)
    257  		{
    258  			string value = "AspNet-Menu-NonLink";
    259  			if (item != null)
    260  			{
    261  				if (((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null)) ||
    262  					((item.Depth >= menu.StaticDisplayLevels) && (menu.DynamicItemTemplate != null)))
    263  				{
    264  					value = "AspNet-Menu-Template";
    265  				}
    266  				else if (IsLink(item))
    267  				{
    268  					value = "AspNet-Menu-Link";
    269  				}
    270  				string selectedStatusClass = GetSelectStatusClass(item);
    271  				if (!String.IsNullOrEmpty(selectedStatusClass))
    272  				{
    273  					value += " " + selectedStatusClass;
    274  				}
    275  			}
    276  			return value;
    277  		}
    278  
    279  		private string GetSelectStatusClass(MenuItem item)
    280  		{
    281  			string value = "";
    282  			if (item.Selected)
    283  			{
    284  				value += " AspNet-Menu-Selected";
    285  			}
    286  			else if (IsChildItemSelected(item))
    287  			{
    288  				value += " AspNet-Menu-ChildSelected";
    289  			}
    290  			else if (IsParentItemSelected(item))
    291  			{
    292  				value += " AspNet-Menu-ParentSelected";
    293  			}
    294  			return value;
    295  		}
    296  
    297  		private bool IsChildItemSelected(MenuItem item)
    298  		{
    299  			bool bRet = false;
    300  
    301  			if ((item != null) && (item.ChildItems != null))
    302  			{
    303  				bRet = IsChildItemSelected(item.ChildItems);
    304  			}
    305  
    306  			return bRet;
    307  		}
    308  
    309  		private bool IsChildItemSelected(MenuItemCollection items)
    310  		{
    311  			bool bRet = false;
    312  
    313  			if (items != null)
    314  			{
    315  				foreach (MenuItem item in items)
    316  				{
    317  					if (item.Selected || IsChildItemSelected(item.ChildItems))
    318  					{
    319  						bRet = true;
    320  						break;
    321  					}
    322  				}
    323  			}
    324  
    325  			return bRet;
    326  		}
    327  
    328  		private bool IsParentItemSelected(MenuItem item)
    329  		{
    330  			bool bRet = false;
    331  
    332  			if ((item != null) && (item.Parent != null))
    333  			{
    334  				if (item.Parent.Selected)
    335  				{
    336  					bRet = true;
    337  				}
    338  				else
    339  				{
    340  					bRet = IsParentItemSelected(item.Parent);
    341  				}
    342  			}
    343  
    344  			return bRet;
    345  		}
    346  
    347  		/// <summary>
    348  		/// Clear the embedded header styles that ASP.NET automatically adds for the menu.
    349  		/// </summary>
    350  		/// <param name="e"></param>
    351  		/// <remarks>
    352  		/// Patch provided by LonelyRollingStar via CodePlex issue #2714:
    353  		/// 
    354  		/// The ASP.NET Menu control automatically adds several styles to the embedded header style. For example:
    355  		/// 
    356  		/// <c>.ctl00_ucMenu_MenuCBM_0 { background-color:white;visibility:hidden;display:none;;left:0px;top:0px; }</c>
    357  		/// 
    358  		/// This is unnecessary and probably breaks your ability to fully style your menu with external stylesheets.
    359  		/// 
    360  		/// The culprit is an internal method of the Menu control called EnsureRenderSettings. It calls 
    361  		/// <c>this.Page.Header.StyleSheet.CreateStyleRule()</c> several times, adding style rules to the embedded stylesheet. 
    362  		/// <c>EnsureRenderSettings</c> is called at the beginning of the Menu's <c>OnPreRender</c> method. 
    363  		/// 
    364  		/// Hey, the menu adapter exposes OnPreRender! That means we're getting closer to an answer, right? 
    365  		/// Right, but if we override <c>OnPreRender</c> and don't call the base implementation we'll be 
    366  		/// missing some important functionality. This uses internal methods so we cannot emulate it in the menu adapter.
    367  		/// 
    368  		/// The solution is a bit of a hack, but it's quick and direct. We override <c>OnPreRender</c> and after calling 
    369  		/// the base implementation as normal, we clear the embedded header styles that were just added.
    370  		/// </remarks>
    371  		protected override void OnPreRender(EventArgs e)
    372  		{
    373  			base.OnPreRender(e);
    374  
    375  			// Clear the embedded header styles that ASP.NET automatically adds for the menu
    376  			ArrayList selectorStyles = Helpers.GetPrivateField(Page.Header.StyleSheet, "_selectorStyles") as ArrayList;
    377  			if (selectorStyles != null)
    378  			{
    379  				selectorStyles.Clear();
    380  			}
    381  		}
    382  
    383  	}
    384  }
    385  
    
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, March 13, 2008 1:05 AM

All replies

  • User-656867934 posted

    Make sure you are working with the latest version of the source code, then try this: Locate the BuildItem & BuildItems functions in the MenuAdapter.cs file, and make the changes indicated below:

     

    // Locate the foreach loop in BuildItems, and modify it to look like this:
    int i = 0;
    foreach (MenuItem item in items)
    {
    	BuildItem(item, writer, i++);
    }
    
    And for BuildItem():
     
    // Modify the next line, add the , int i
    private void BuildItem(MenuItem item, HtmlTextWriter writer, int i)
    {
        Menu menu = Control as Menu;
        if ((menu != null) && (item != null) && (writer != null))
        {
    	    writer.WriteLine();
    	    writer.WriteBeginTag("li");
                // You want to add this next line to your code
                writer.WriteAttribute("id", String.Format("menuLevel_{0}_{1}", item.Depth, i.ToString()));
     

    Recompile the DLL, drop it in your bin directory or put it in your GAC, and your done. Here is the code in its' entirety:

    1    using System;
    2    using System.Collections;
    3    using System.Reflection;
    4    using System.IO;
    5    using System.Web;
    6    using System.Web.Configuration;
    7    using System.Web.UI;
    8    using System.Web.UI.WebControls;
    9    using System.Web.UI.HtmlControls;
    10   
    11   namespace CSSFriendly
    12   {
    13   	public class MenuAdapter : System.Web.UI.WebControls.Adapters.MenuAdapter
    14   	{
    15   		private WebControlAdapterExtender _extender = null;
    16   		private WebControlAdapterExtender Extender
    17   		{
    18   			get
    19   			{
    20   				if (((_extender == null) && (Control != null)) ||
    21   					((_extender != null) && (Control != _extender.AdaptedControl)))
    22   				{
    23   					_extender = new WebControlAdapterExtender(Control);
    24   				}
    25   
    26   				System.Diagnostics.Debug.Assert(_extender != null, "CSS Friendly adapters internal error", "Null extender instance");
    27   				return _extender;
    28   			}
    29   		}
    30   
    31   		protected override void OnInit(EventArgs e)
    32   		{
    33   			base.OnInit(e);
    34   
    35   			if (Extender.AdapterEnabled)
    36   			{
    37   				RegisterScripts();
    38   			}
    39   		}
    40   
    41   		private void RegisterScripts()
    42   		{
    43   			Extender.RegisterScripts();
    44   
    45   			/* 
    46   			 * Modified for support of compiled CSSFriendly assembly
    47   			 * 
    48   			 * We will first search for embedded JavaScript files. If they are not
    49   			 * found, we default to the standard approach.
    50   			 */
    51   
    52   			Type type = this.GetType();
    53   
    54   			// MenuAdapter.js
    55   			Helpers.RegisterClientScript("CSSFriendly.JavaScript.MenuAdapter.js", type, this.Page);
    56   
    57   			// Menu.css
    58   			Helpers.RegisterEmbeddedCSS("CSSFriendly.CSS.Menu.css", type, this.Page);
    59   
    60   			// Only send IEMenu6.css if it's IE version <7
    61   			if (this.Browser.Browser.ToUpper().IndexOf("IE") >= 0
    62   				&& this.Browser.MajorVersion < 7)
    63   			{
    64   				Helpers.RegisterEmbeddedCSS("CSSFriendly.CSS.BrowserSpecific.IEMenu6.css", type, this.Page);
    65   			}
    66   		}
    67   
    68   		protected override void RenderBeginTag(HtmlTextWriter writer)
    69   		{
    70   			if (Extender.AdapterEnabled)
    71   			{
    72   				Extender.RenderBeginTag(writer, "AspNet-Menu-" + Control.Orientation.ToString());
    73   			}
    74   			else
    75   			{
    76   				base.RenderBeginTag(writer);
    77   			}
    78   		}
    79   
    80   		protected override void RenderEndTag(HtmlTextWriter writer)
    81   		{
    82   			if (Extender.AdapterEnabled)
    83   			{
    84   				Extender.RenderEndTag(writer);
    85   			}
    86   			else
    87   			{
    88   				base.RenderEndTag(writer);
    89   			}
    90   		}
    91   
    92   		protected override void RenderContents(HtmlTextWriter writer)
    93   		{
    94   			if (Extender.AdapterEnabled)
    95   			{
    96   				writer.Indent++;
    97   				BuildItems(Control.Items, true, writer);
    98   				writer.Indent--;
    99   				writer.WriteLine();
    100  			}
    101  			else
    102  			{
    103  				base.RenderContents(writer);
    104  			}
    105  		}
    106  
    107  		private void BuildItems(MenuItemCollection items, bool isRoot, HtmlTextWriter writer)
    108  		{
    109  			if (items.Count > 0)
    110  			{
    111  				writer.WriteLine();
    112  
    113  				writer.WriteBeginTag("ul");
    114  				if (isRoot)
    115  				{
    116  					writer.WriteAttribute("class", "AspNet-Menu");
    117  				}
    118  				writer.Write(HtmlTextWriter.TagRightChar);
    119  				writer.Indent++;
    120  
    121                  int i = 0;
    122                  foreach (MenuItem item in items)
    123                  {
    124  	                BuildItem(item, writer, i++);
    125                  }
    126  
    127  				writer.Indent--;
    128  				writer.WriteLine();
    129  				writer.WriteEndTag("ul");
    130  			}
    131  		}
    132  
    133          private void BuildItem(MenuItem item, HtmlTextWriter writer, int i)
    134          {
    135              Menu menu = Control as Menu;
    136              if ((menu != null) && (item != null) && (writer != null))
    137              {
    138                  writer.WriteLine();
    139                  writer.WriteBeginTag("li");
    140                  writer.WriteAttribute("id", String.Format("menuLevel_{0}_{1}", item.Depth, i.ToString()));
    141  
    142  				string theClass = (item.ChildItems.Count > 0) ? "AspNet-Menu-WithChildren" : "AspNet-Menu-Leaf";
    143  				string selectedStatusClass = GetSelectStatusClass(item);
    144  				if (!String.IsNullOrEmpty(selectedStatusClass))
    145  				{
    146  					theClass += " " + selectedStatusClass;
    147  				}
    148  				writer.WriteAttribute("class", theClass);
    149  
    150  				writer.Write(HtmlTextWriter.TagRightChar);
    151  				writer.Indent++;
    152  				writer.WriteLine();
    153  
    154  				if (((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null)) ||
    155  					((item.Depth >= menu.StaticDisplayLevels) && (menu.DynamicItemTemplate != null)))
    156  				{
    157  					writer.WriteBeginTag("div");
    158  					writer.WriteAttribute("class", GetItemClass(menu, item));
    159  					writer.Write(HtmlTextWriter.TagRightChar);
    160  					writer.Indent++;
    161  					writer.WriteLine();
    162  
    163  					MenuItemTemplateContainer container = new MenuItemTemplateContainer(menu.Items.IndexOf(item), item);
    164  					if ((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null))
    165  					{
    166  						menu.StaticItemTemplate.InstantiateIn(container);
    167  					}
    168  					else
    169  					{
    170  						menu.DynamicItemTemplate.InstantiateIn(container);
    171  					}
    172  					container.DataBind();
    173  					container.RenderControl(writer);
    174  
    175  					writer.Indent--;
    176  					writer.WriteLine();
    177  					writer.WriteEndTag("div");
    178  				}
    179  				else
    180  				{
    181  					if (IsLink(item))
    182  					{
    183  						writer.WriteBeginTag("a");
    184  						if (!String.IsNullOrEmpty(item.NavigateUrl))
    185  						{
    186  							writer.WriteAttribute("href", Page.Server.HtmlEncode(menu.ResolveClientUrl(item.NavigateUrl)));
    187  						}
    188  						else
    189  						{
    190  							writer.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(menu, "b" + item.ValuePath.Replace(menu.PathSeparator.ToString(), "\\"), true));
    191  						}
    192  
    193  						writer.WriteAttribute("class", GetItemClass(menu, item));
    194  						WebControlAdapterExtender.WriteTargetAttribute(writer, item.Target);
    195  
    196  						if (!String.IsNullOrEmpty(item.ToolTip))
    197  						{
    198  							writer.WriteAttribute("title", item.ToolTip);
    199  						}
    200  						else if (!String.IsNullOrEmpty(menu.ToolTip))
    201  						{
    202  							writer.WriteAttribute("title", menu.ToolTip);
    203  						}
    204  						writer.Write(HtmlTextWriter.TagRightChar);
    205  						writer.Indent++;
    206  						writer.WriteLine();
    207  					}
    208  					else
    209  					{
    210  						writer.WriteBeginTag("span");
    211  						writer.WriteAttribute("class", GetItemClass(menu, item));
    212  						writer.Write(HtmlTextWriter.TagRightChar);
    213  						writer.Indent++;
    214  						writer.WriteLine();
    215  					}
    216  
    217  					if (!String.IsNullOrEmpty(item.ImageUrl))
    218  					{
    219  						writer.WriteBeginTag("img");
    220  						writer.WriteAttribute("src", menu.ResolveClientUrl(item.ImageUrl));
    221  						writer.WriteAttribute("alt", !String.IsNullOrEmpty(item.ToolTip) ? item.ToolTip : (!String.IsNullOrEmpty(menu.ToolTip) ? menu.ToolTip : item.Text));
    222  						writer.Write(HtmlTextWriter.SelfClosingTagEnd);
    223  					}
    224  
    225  					writer.Write(item.Text);
    226  
    227  					if (IsLink(item))
    228  					{
    229  						writer.Indent--;
    230  						writer.WriteEndTag("a");
    231  					}
    232  					else
    233  					{
    234  						writer.Indent--;
    235  						writer.WriteEndTag("span");
    236  					}
    237  
    238  				}
    239  
    240  				if ((item.ChildItems != null) && (item.ChildItems.Count > 0))
    241  				{
    242  					BuildItems(item.ChildItems, false, writer);
    243  				}
    244  
    245  				writer.Indent--;
    246  				writer.WriteLine();
    247  				writer.WriteEndTag("li");
    248  			}
    249  		}
    250  
    251  		private bool IsLink(MenuItem item)
    252  		{
    253  			return (item != null) && item.Enabled && ((!String.IsNullOrEmpty(item.NavigateUrl)) || item.Selectable);
    254  		}
    255  
    256  		private string GetItemClass(Menu menu, MenuItem item)
    257  		{
    258  			string value = "AspNet-Menu-NonLink";
    259  			if (item != null)
    260  			{
    261  				if (((item.Depth < menu.StaticDisplayLevels) && (menu.StaticItemTemplate != null)) ||
    262  					((item.Depth >= menu.StaticDisplayLevels) && (menu.DynamicItemTemplate != null)))
    263  				{
    264  					value = "AspNet-Menu-Template";
    265  				}
    266  				else if (IsLink(item))
    267  				{
    268  					value = "AspNet-Menu-Link";
    269  				}
    270  				string selectedStatusClass = GetSelectStatusClass(item);
    271  				if (!String.IsNullOrEmpty(selectedStatusClass))
    272  				{
    273  					value += " " + selectedStatusClass;
    274  				}
    275  			}
    276  			return value;
    277  		}
    278  
    279  		private string GetSelectStatusClass(MenuItem item)
    280  		{
    281  			string value = "";
    282  			if (item.Selected)
    283  			{
    284  				value += " AspNet-Menu-Selected";
    285  			}
    286  			else if (IsChildItemSelected(item))
    287  			{
    288  				value += " AspNet-Menu-ChildSelected";
    289  			}
    290  			else if (IsParentItemSelected(item))
    291  			{
    292  				value += " AspNet-Menu-ParentSelected";
    293  			}
    294  			return value;
    295  		}
    296  
    297  		private bool IsChildItemSelected(MenuItem item)
    298  		{
    299  			bool bRet = false;
    300  
    301  			if ((item != null) && (item.ChildItems != null))
    302  			{
    303  				bRet = IsChildItemSelected(item.ChildItems);
    304  			}
    305  
    306  			return bRet;
    307  		}
    308  
    309  		private bool IsChildItemSelected(MenuItemCollection items)
    310  		{
    311  			bool bRet = false;
    312  
    313  			if (items != null)
    314  			{
    315  				foreach (MenuItem item in items)
    316  				{
    317  					if (item.Selected || IsChildItemSelected(item.ChildItems))
    318  					{
    319  						bRet = true;
    320  						break;
    321  					}
    322  				}
    323  			}
    324  
    325  			return bRet;
    326  		}
    327  
    328  		private bool IsParentItemSelected(MenuItem item)
    329  		{
    330  			bool bRet = false;
    331  
    332  			if ((item != null) && (item.Parent != null))
    333  			{
    334  				if (item.Parent.Selected)
    335  				{
    336  					bRet = true;
    337  				}
    338  				else
    339  				{
    340  					bRet = IsParentItemSelected(item.Parent);
    341  				}
    342  			}
    343  
    344  			return bRet;
    345  		}
    346  
    347  		/// <summary>
    348  		/// Clear the embedded header styles that ASP.NET automatically adds for the menu.
    349  		/// </summary>
    350  		/// <param name="e"></param>
    351  		/// <remarks>
    352  		/// Patch provided by LonelyRollingStar via CodePlex issue #2714:
    353  		/// 
    354  		/// The ASP.NET Menu control automatically adds several styles to the embedded header style. For example:
    355  		/// 
    356  		/// <c>.ctl00_ucMenu_MenuCBM_0 { background-color:white;visibility:hidden;display:none;;left:0px;top:0px; }</c>
    357  		/// 
    358  		/// This is unnecessary and probably breaks your ability to fully style your menu with external stylesheets.
    359  		/// 
    360  		/// The culprit is an internal method of the Menu control called EnsureRenderSettings. It calls 
    361  		/// <c>this.Page.Header.StyleSheet.CreateStyleRule()</c> several times, adding style rules to the embedded stylesheet. 
    362  		/// <c>EnsureRenderSettings</c> is called at the beginning of the Menu's <c>OnPreRender</c> method. 
    363  		/// 
    364  		/// Hey, the menu adapter exposes OnPreRender! That means we're getting closer to an answer, right? 
    365  		/// Right, but if we override <c>OnPreRender</c> and don't call the base implementation we'll be 
    366  		/// missing some important functionality. This uses internal methods so we cannot emulate it in the menu adapter.
    367  		/// 
    368  		/// The solution is a bit of a hack, but it's quick and direct. We override <c>OnPreRender</c> and after calling 
    369  		/// the base implementation as normal, we clear the embedded header styles that were just added.
    370  		/// </remarks>
    371  		protected override void OnPreRender(EventArgs e)
    372  		{
    373  			base.OnPreRender(e);
    374  
    375  			// Clear the embedded header styles that ASP.NET automatically adds for the menu
    376  			ArrayList selectorStyles = Helpers.GetPrivateField(Page.Header.StyleSheet, "_selectorStyles") as ArrayList;
    377  			if (selectorStyles != null)
    378  			{
    379  				selectorStyles.Clear();
    380  			}
    381  		}
    382  
    383  	}
    384  }
    385  
    
     
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, March 13, 2008 1:05 AM
  • User-943454799 posted
    Thanks! I'm using Treeview control, so I modified TreeViewAdapter.cs, as per your comments, and it's now adding id tags to each <li> node. **One note I would make to anyone making the same modification, you might want to make sure your id attrbutes are unique. If you used this same code in both the MenuAdapter.cs and TreeViewAdapter.cs files, then you would have nodes that would not have unique id attributes - instead you might want to edit each file so that the id attributes are unique. For example, I modified TreeViewAdapter.cs to look like this:

    writer.WriteAttribute("id", String.Format("tv_menuLevel_{0}_{1}", item.Depth, i.ToString()));

    Thursday, March 13, 2008 1:31 PM