Reputation: 3205
I'm trying to make a tabbed menu for the asp.net website I'm working on. One of the pre-requisite is obviously to color the current tab differently, so the user can know on which tab is currently is.
To do this, I made this method in my code-behind:
Protected Function GetCssClass(ByVal ctrl As LinkButton) As String
If ctrl.ID = currentLink Then
Return "current"
Else
Return String.Empty
End If
End Function
and I call the method like this in my aspx page:
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="/Default.aspx" CssClass="<%#GetCssClass(LinkButton1) %>" >Home</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="/Directory/page1.aspx" CssClass="<%#GetCssClass(LinkButton2) %>" >Page1</asp:LinkButton>
But the method is never hit... As I understand, the method should be called each time the LinkButton
is drawn...
Does someone have an idea why?
Thanks in advance !
Edit: Just as a precision, all this code is in the masterpage.
Edit2: Here are the changes I made according to Quagland's suggestion.
In the aspx masterpage:
<asp:HiddenField ID="currentLink" runat="server" />
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="/Default.aspx" OnClick="LinkButton_Click" OnPreRender="LinkButton_PreRender" >Home</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="/OtherDirectory/Page1.aspx" OnClick="LinkButton_Click" OnPreRender="LinkButton_PreRender" >Page1</asp:LinkButton>
<asp:LinkButton ID="LinkButton3" runat="server" PostBackUrl="/OtherDirectory/Page2.aspx" OnClick="LinkButton_Click" OnPreRender="LinkButton_PreRender" >Page2</asp:LinkButton>
<asp:LinkButton ID="LinkButton4" runat="server" PostBackUrl="/OtherDirectory/Page3.aspx" OnClick="LinkButton_Click" OnPreRender="LinkButton_PreRender" >Page3</asp:LinkButton>
And in the code behind:
Protected Sub LinkButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles LinkButton1.Click, LinkButton2.Click, LinkButton3.Click, LinkButton4.Click, LinkButton5.Click, LinkButton6.Click, LinkButton7.Click, LinkButton8.Click
Dim lnk As LinkButton = CType(sender, LinkButton)
currentLink.Value = lnk.ID
End Sub
Protected Function GetCssClass(ByVal ctrl As LinkButton) As String
If ctrl.ID = currentLink.Value Then
Return "current"
Else
Return String.Empty
End If
End Function
Protected Sub LinkButton_PreRender(ByVal sender As Object, ByVal e As EventArgs) Handles LinkButton1.PreRender, LinkButton2.PreRender, LinkButton3.PreRender, LinkButton4.PreRender, LinkButton5.PreRender, LinkButton6.PreRender, LinkButton7.PreRender, LinkButton8.PreRender
Dim lnk As LinkButton = CType(sender, LinkButton)
lnk.CssClass = GetCssClass(lnk)
End Sub
The problem is now that the click event is not always fired. On first click, nothing happens, but on second click on a tab, the click event is correctly triggered. Any clue ?
Edit3: Could it be that the value stored in the hidden field is reset each time the masterpage is reloaded (I mean, each link points to a couple masterpage + content page) ?
Upvotes: 2
Views: 2264
Reputation: 4753
I have quickly tested a solution that might work for you. I'm just not sure where your 'currentlink' variable comes from. I have implemented it as a hidden field here.
In Masterpage.aspx:
<asp:HiddenField ID="currentLink" runat="server" />
<asp:LinkButton ID="LinkButton1" runat="server">Home</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server">Page1</asp:LinkButton>
In code behind: use your original GetCssClass function add this:
Protected Sub LinkButton_PreRender(ByVal sender As Object, ByVal e As System.EventArgs)
Handles LinkButton1.PreRender, LinkButton2.PreRender
Dim lnk As LinkButton = CType(sender, LinkButton)
lnk.CssClass = GetCssClass(lnk)
End Sub
I have put it in PreRender because i was using the LinkButton click events to set the hidden field value (and Click happens after Load but before PreRender):
Protected Sub LinkButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles LinkButton1.Click, LinkButton2.Click
Dim lnk As LinkButton = CType(sender, LinkButton)
currentLink.Value = lnk.ID
End Sub
also, if there are numerous Linkbuttons, you may want to declare like:
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton_Click" OnPreRender="LinkButton_PreRender">Home</asp:LinkButton>
EDIT: Here is another solution that will work with cross page postbacks. Not much code but you'll need to put some on every page. Anyway:
Masterpage.aspx:
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="Default.aspx">Home</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="Page1.aspx">Page1</asp:LinkButton>
<asp:LinkButton ID="LinkButton3" runat="server" PostBackUrl="Page2.aspx">Page2</asp:LinkButton>
<asp:LinkButton ID="LinkButton4" runat="server" PostBackUrl="Page3.aspx">Page3</asp:LinkButton>
Masterpage.aspx.vb:
Public Sub SetCssClass(ByVal ctrl As String)
CType(FindControl(ctrl), LinkButton).CssClass = "current"
End Sub
All content pages: *.aspx: add this directive to create a strongly typed reference to the masterpage
<%@ MasterType VirtualPath="~/MasterPage.master" %>
*.aspx.vb:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Master.SetCssClass("LinkButton1") '' << put the name of the relevant link button here
End Sub
Upvotes: 1
Reputation: 10764
I'm not sure why <%= %> isn't working but personally I don't like to mix code and markup, I like to keep them completely separate.
I would suggest setting the CSS class in code perhaps on the page load event.
lnkPopulate.CssClass = "current"
Upvotes: 1
Reputation: 3282
Set the CssClass in the code-behind. This will state your intent more clearly than calling DataBind on your linkbuttons if you use databinding syntax. Since you're doing it for multiple controls maybe stick them in a method called ApplyCssClasses.
Upvotes: 1
Reputation: 2991
<%# ... %>
will work if you're OK with doing LinkButton1.DataBind()
in your code-behind at the appropriate time.
Upvotes: 0
Reputation: 109035
You need to use <%= ... %>
(i.e. replace #
with =
).
The hash form is used with data binding, you want to just create output.
For .NET 4 prefer <%: ... %>
(use a colon) to automatically do HTML encoding.
Upvotes: 2