Shimrod
Shimrod

Reputation: 3205

"Inline" function call: function is never hit

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

Answers (5)

Beno
Beno

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

Fishcake
Fishcake

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

zincorp
zincorp

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

Chris
Chris

Reputation: 2991

<%# ... %> will work if you're OK with doing LinkButton1.DataBind() in your code-behind at the appropriate time.

Upvotes: 0

Richard
Richard

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

Related Questions