Thursday, October 28, 2004 - Posts

asp:menu - mark the current tab selected

Using a new asp:menu control on a Whidbey master page. I'm treating the menu tab(items) as navigateUrls, and not as command postbacks. Originally, I added code for selecting the current menu item to each of the aspx pages that represent one of the navigateUrls of the menu tabs. The code would look something like this:

DirectCast(Me.Master.FindControl("MainMenu"), Menu).Items(0).Selected = True

Unfortunately, this meant that each aspx page that was navigated as part of the menu system would need to have knowledge of where in the menu it was located (i.e. items(i)). I didn't care for this approach because if I ever wanted to change the tab order of the menu, I would then need to touch each of the respective aspx pages to change this line.

The next thought I had was using configuration to control the ordinal in the items collection. So, I could add config keys like this:

<add key=MyMenu:MyPage value=0/>
<add key=MyMenu:MyOtherPage value=1/>

Then the line of code in each aspx page could be re-written as:

DirectCast(Me.Master.FindControl("MainMenu"), Menu).Items(GetConfig("MyPage")).Selected = True

Where GetConfig is just a method that gets this page's respective ordinal value from the configuration. This was better, but wasn't good enough. I really didn't want each page to even require this single line of code. The menu itself, or at least code on the page where the menu lives should be making this decision to mark a tab item as selected.

I then came up with an approach of adding the tab menu selection code directly to the master page that contains the menu. I added the following code to my master page:

Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
     Dim thisPage As String
     thisPage = Page.GetType.Name
     For Each item As MenuItem In DefaultMenu.Items
          If item.ValuePath = thisPage Then
              item.Selected = True
          Else
              item.Selected = False
          End If
     Next
End Sub

Now all the code to handle this is in one place, and its in a place that makes more sense; the master page that houses the asp:menu. In order to make this work, I simply add the class name of the page; i.e. MyPage_aspx as the menu items value (not it's navigate Url). I choose to not get involved with inspecting the url, because I didn't want to worry about redirects, transfers, or maybe some other tricks I'll need to use down the road that involve some behind the scenes url munging.

I kinda like this approach for now, it's simple, in one place, and the only responsibility to make it work lies with the process of adding menu items, which is where I think it should be.

Now, I'm waiting for somebody to post back, “hey, why didn't you just set the AutoSelectCurrentMenuTab property on the asp:menu control”. Unfortunately, if such a property exist I didn't know about it ;-)