Nelson Pires
Nelson Pires

Reputation: 321

Find control in Web Forms inside a repeater

I'm unable to find a Literal inside a Repeater that is in another UserControl.

I have the following UserControl:

<nav role="navigation">
<ul>
    <li><a href="/"<asp:Literal id="litNavHomeActive" runat="server" />>Home</a></li>
<asp:Repeater id="rpt_NavItem" runat="server" OnItemDataBound="rpt_OnItemDataBound">
<ItemTemplate>
    <li><a href="/<asp:Literal id="lit_Url" runat="server" />/"<asp:Literal id="lit_NavActive" runat="server" />><asp:Literal id="lit_Title" runat="server" /></a></li>
</ItemTemplate>
</asp:Repeater>
</ul>
<div class="cb"></div>
</nav>

This is placed inside a MasterPage and from another ContentPage, I'm trying to find "lit_NavActive" and hide it.

I am using this:

Repeater rpt = ((Theme)Page.Master).FindControl("Navigation").FindControl("rpt_NavItem") as Repeater;
Literal lit = rpt.FindControl("lit_NavActive");
if (lit != null) { lit.Visible = false; }

And its not working, if I do rpt.Visible = false; that works fine in hiding the whole repeater, so I'm close but fail to find the Literal (lit_NavActive) inside the Repeater. Any ideas?

Upvotes: 3

Views: 4618

Answers (3)

Roger Willcocks
Roger Willcocks

Reputation: 1659

I've seen many of these answers, but I was looking to pass the control in the repeater item into a method, from within the template itself (in the "HTML")

And the answer for doing that I haven't seen, but is that you can do:

Container.FindControl("lit_NavActive")

Container is the RepeaterItem you are currently in.

<asp:Checkbox id="chkValue" Checked='<%# GetCheckboxValue((CheckBox)Container.FindControl("chkValue"), Eval("SettingValue")) %.' />

In this case I was using it to turn the control red if the setting value was not a valid Boolean.

Upvotes: 0

j.f.
j.f.

Reputation: 3939

Since the repeater is a data bound control, each row of the repeater would consist of a literal named "lit_NavActive". Because of this, it names them uniquely on the page. If you view the source of your page, you would notice them named something like this:

rpt_NavItem_ctl101_lit_NavActive
rpt_NavItem_ctl102_lit_NavActive
rpt_NavItem_ctl103_lit_NavActive

So when you try to find "lit_NavActive" on the entire repeater, it can't find it because "lit_NavActive" doesn't exist like that. What you need to do is find "lit_NavActive" within a row of the repeater.

foreach(RepeaterItem item in rpt_NavItem.Items)
{
    Literal lit_NavActive = (Literal)item.FindControl("lit_NavActive");
    if (lit_NavActive != null) 
    { 
        lit_NavActive.Visible = false; 
    }
}

Edit: It's possible all this stuff:

<li><a href="/<asp:Literal id="lit_Url" runat="server" />/"<asp:Literal id="lit_NavActive" runat="server" />><asp:Literal id="lit_Title" runat="server" /></a></li>

is causing some problems with the opening and closing of controls. I would recommend switching to an <asp:HyperLink>. This will make everything much cleaner and easier to deal with.

<asp:Repeater id="rpt_NavItem" runat="server" 
    OnItemDataBound="rpt_OnItemDataBound">
    <ItemTemplate>
        <asp:HyperLink ID="hyp" runat="server"></asp:HyperLink>
    </ItemTemplate>
</asp:Repeater>

Then in your ItemDataBound handler, set the properties of the HyperLink rather than the Literals.

protected void rpt_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
    HyperLink hyp = (HyperLink)e.Item.FindControl("hyp");
    hyp.NavigateUrl = // your lit_Url value (ex. "http://www.google.com")
    hyp.CssClass = // your lit_NavActive value (ex. "active")
    hyp.Text = // your lit_Title value (ex. "Google")
}

Then getting back to your original foreach loop, find the HyperLink instead.

foreach(RepeaterItem item in rpt_NavItem.Items)
{
    HyperLink hyp = (HyperLink)item.FindControl("hyp");
    if (hyp != null) 
    { 
        hyp.Visible = false; 
    }
}

Upvotes: 1

Niels Filter
Niels Filter

Reputation: 4528

You need to find the control on a RepeaterItem, not on the Repeater self

foreach (var item in rpt.Items)
{
   Literal lit = item.FindControl("lit_NavActive");
   if (lit != null) { lit.Visible = false; }
}

Remember that a Repeater "repeats" items, so there may be multiple literals within your Repeater. The above code hides will all the Literals.

If you need to hide a "specific" on, then in the loop, you should apply your condition and decide whether to show or hide it.

Alternatively consider using ItemDataBound event of the Repeater.

Upvotes: 4

Related Questions