Page view counter

dynamically set menu items width to percentage programmatically

Last post 03-19-2008 9:24 AM by Schmakt. 4 replies.

Sort Posts:

  • dynamically set menu items width to percentage programmatically

    02-20-2008, 11:54 PM
    • Loading...
    • Schmakt
    • Joined on 12-06-2007, 3:24 PM
    • Posts 96
    • Points 99

    All... I feel like I'm missing one little switch or something, but I can't figure out what it is...

    I have a menu in a masterpage.
    The menu's DataSource is set to a SiteMap (which map depends on the user's location)
    security trimming is enabled

    Everything works except for 2 things:
    - The menu items don't have an equal width.  The menu is 100%, and I want each item to take up an equal amount of space.
    - And I want the dynamic menus to be equal in width to their parent staticitems.

     Here is my menu:
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" SiteMapProvider="" />
    <asp:Menu ID="Menu1" runat="server" Orientation="Horizontal" Width="100%" ForeColor="White" StaticMenuItemStyle-ItemSpacing="0"
             
    StaticEnableDefaultPopOutImage="false" StaticMenuStyle-HorizontalPadding="0" StaticMenuStyle-VerticalPadding="0">
    <StaticHoverStyle BackColor="#3366CC" ForeColor="White" />
    <StaticMenuStyle BackColor="#999999" ForeColor="White" />
    <DynamicHoverStyle BackColor="#3366CC" ForeColor="White" />
    <DynamicMenuStyle BackColor="#999999" ForeColor="White" />
    <StaticMenuItemStyle BackColor="#999999" ForeColor="White" BorderWidth="1" BorderColor="White" />
    <StaticSelectedStyle BackColor="#3366CC" ForeColor="White" BorderWidth="1" BorderColor="White" />
    <DynamicMenuItemStyle BackColor="#999999" ForeColor="White" BorderWidth="1" BorderColor="White" />
    <DynamicSelectedStyle BackColor="#3366CC" ForeColor="White" BorderWidth="1" BorderColor="White" />
    </asp:Menu>

     Here is my code-behind in which I attempt to modify the width's of the MenuItems using a percentage:
    Menu1.Width = Unit.Percentage(100);
    Menu1.StaticMenuItemStyle.Width =
    Unit.Percentage(varWidth);
    Menu1.StaticMenuStyle.Width =
    Unit.Percentage(100);
    Menu1.DynamicMenuStyle.Width =
    Unit.Percentage(varWidth);
    Menu1.DynamicMenuItemStyle.Width =
    Unit.Percentage(100);
    Menu1.DataSourceID =
    "SiteMapDataSource1";
    Menu1.DataBind();

    That snippet is from a function that I have called from Page_Load and Page_Init...
    The first part of the function is just determining "varWidth" (100 / number of Items), but I have tried replacing the variable with integers and it doesn't seem to matter.

     

    Is there some stupid easy way to just make each Item an equal width within the menu?  Thank you!

    Filed under: ,
  • Re: dynamically set menu items width to percentage programmatically

    02-24-2008, 9:33 PM
    Answer

    Hi,

    Schmakt:

    - The menu items don't have an equal width.  The menu is 100%, and I want each item to take up an equal amount of space.
    - And I want the dynamic menus to be equal in width to their parent staticitems..

    You can not set the menuitem's width directly, but you can wrap menuitem with a div control, then set the div's width, so you can wrap the menuitem in the menuitemdatabound event, for example:

     protected void Menu1_MenuItemDataBound(object sender, TreeNodeEventArgs e)
        {
                   e.Item.Text = "<div style='width:100px; color:Yellow; background-color:Orange' >" + e.Item.Text + "</div>";
        }

    Hope it helps.

    Amanda Wang
    Microsoft Online Community Support

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
  • Re: dynamically set menu items width to percentage programmatically

    02-25-2008, 1:02 PM
    • Loading...
    • Schmakt
    • Joined on 12-06-2007, 3:24 PM
    • Posts 96
    • Points 99

    thank you - that definitely starts to answer my question...

    however, I'd like these width values to be percentages... if I do what you suggest and set the percentage to 100, the div simply occupies all of the space given to it in the menu control.  So I can certainly calculate the number of pixels based on the width of the page, but when the user resizes the page, it would require that I recalculate the values and reset the menu.

    Is there a way to do this so that the percentage width of the divs you mentioned are percentage of the window as opposed to the percentage of the MenuItem Container in which they find themselves?

     

    So, basically, I want a menu with a variable number of options... the menu should take up the entire width of the page, and the options should be equally spaced within the menu.  Dynamic options should then be the same width as their parent.  Does that make sense?  Is it possible to do without specifying the pixel width of the items?  Thanks again!

  • Re: dynamically set menu items width to percentage programmatically

    02-26-2008, 10:04 PM
    Answer

    Hi,

    Maybe you can try to use css menu adapter of the ASP.NET 2.0 CSS Friendly Control Adapters.

    It is use the nested <ul> tags instead of the nested <table> tags to render the menu control, so it is much more flexibility  to control the lay out of the menuitems.

    Hope it helps.

    Amanda Wang
    Microsoft Online Community Support

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
  • Re: dynamically set menu items width to percentage programmatically

    03-19-2008, 9:24 AM
    Answer
    • Loading...
    • Schmakt
    • Joined on 12-06-2007, 3:24 PM
    • Posts 96
    • Points 99

    Sorry so long... I meant to say thanks for the adapter suggestion... I definitely never would have solved it w/o that.

    After I applied the adapter, I was able to modify it slightly by giving the required elements an id:
    private void BuildItems(MenuItemCollection items, bool isRoot, HtmlTextWriter writer)
    {
    if (items.Count > 0)
    {
    writer.WriteLine();
    writer.WriteBeginTag(
    "ul");
    if (isRoot)
    {
    writer.WriteAttribute(
    "class", "AspNet-Menu");
    writer.WriteAttribute(
    "id", "ulMenu");
    }
    writer.Write(
    HtmlTextWriter.TagRightChar);
    writer.Indent++;
    foreach (MenuItem item in items)
    {
    BuildItem(item, writer);
    }
    writer.Indent--;
    writer.WriteLine();
    writer.WriteEndTag(
    "ul");
    }
    }
    private void BuildItem(MenuItem item, HtmlTextWriter writer)
    {
    Menu menu = Control as Menu;
    if ((menu != null) && (item != null) && (writer != null))
    {
    writer.WriteLine();
    writer.WriteBeginTag(
    "li");
    string theClass = (item.ChildItems.Count > 0) ? "AspNet-Menu-WithChildren" : "AspNet-Menu-Leaf";
    string selectedStatusClass = GetSelectStatusClass(item);
    if (!String.IsNullOrEmpty(selectedStatusClass))
    {
    theClass +=
    " " + selectedStatusClass;
    }
    writer.WriteAttribute(
    "class", theClass);
    if (item.Parent == null)
    {
    writer.WriteAttribute(
    "id", "liMenu"
    );
    }

    writer.Write(
    HtmlTextWriter.TagRightChar);
    writer.Indent++;
    writer.WriteLine();

     Then, in the .cs file of the page containing the menu, I could the number of menu items and used some javascript code to search for the tags assigned above and to resize each menu element.  I had to use the 99.9 b/c using 100% always pushed the last menu item down a row in Firefox... (strSelectedPageIDs is a comma-separated string of distinct page ID's currently included in the menu - searching for where the ParentPageID is not in that string returns an array of datarows with one row corresponding to each parent node on the menu)

    DataRow[] drs = ds.Tables["dstPages"].Select("ParentPageID NOT IN (" + strSelectedPageIDs + ")");
    if
    (drs.Length != 3 && drs.Length != 0) //Widths are 33% by default... don't *** with it if you don't have to...
    {
    double intNewWidth = (99.9 / (double)drs.Length);
    string strChangeMenuWidth = "<script type='text/javascript'>";
    strChangeMenuWidth +=
    "var ulMenus = document.getElementById('ulMenu');";
    strChangeMenuWidth += "var liMenus = document.getElementsByTagName('li');";
    strChangeMenuWidth += "for (i=0;i<liMenus.length;i++)";
    strChangeMenuWidth +=
    "{";
    strChangeMenuWidth +=
    "if (liMenus[i].id == 'liMenu')";
    strChangeMenuWidth +=
    "{";
    strChangeMenuWidth +=
    "liMenus[i].style.width='" + intNewWidth.ToString() + "%';";
    strChangeMenuWidth += "}";
    strChangeMenuWidth +=
    "}";
    strChangeMenuWidth +=
    "</script>";
    Page.ClientScript.RegisterStartupScript(typeof(Page), "ChangeMenuWidth", strChangeMenuWidth);
    }

Page 1 of 1 (5 items)