views:

222

answers:

5

I'm creating a usercontrol that will have a series of LinkButtons.

I've declared all of my link buttons at the top of my class

LinkButton LB1 = new LinkButton();
LinkButton LB2 = new LinkButton();
//...
LinkButton LB9 = new LinkButton();

now I'd like to be able to create a loop to access all of those link buttons so I don't have to write them all out every time.

I tried something like this within my overridden CreateChildControls() method:

for (int i = 1; i < 10; i++)
        {
            LinkButton lb = (LinkButton)FindControl("LB" + i.ToString());
            lb.Text = i.ToString() + "-Button";
        }

I keep getting an exception saying that lb.Text... is not set to an instance of an object.

I also tried giving all of my LB1, LB2 etc valid Ids.

ie: LB1.ID = "LB1";

still not dice.

how can I do this?

A: 

is it definitely finding the LinkButton? It looks to me like FindControl isn't actually finding the LinkButton.

Hook up the debugger and check that lb isn't actually null.

lomaxx
+1  A: 

FindControl only works once those controls have been added to Controls collection, and that only happens inside the OnInit method. So you're getting an exceptions because the LB1, LB2, etc controls haven't been added to the Controls collection and FindControl is returning null.

One way you could do it is have a List<LinkButton>, then in your Init event handler, add the controls to the list.

Another way, you could use LINQ to loop through your child controls:

var ctrls = Controls.OfType<LinkButton>();

This version would return all LinkButton controls, so I'm not sure if that's exactly what you want. Again, this would only work in the Init event or later in the page cycle.

Additionally

Depending on how your page is structure, you might be better off using a Repeater control. Something like this on your .aspx/ascx file:

<asp:Repeater ID="repeater" runat="server">
    <ItemTemplate>
        <asp:LinkButton ID="btn" runat="server" />
    </ItemTemplate>
</asp:Repeater>

Then in your code behind, you'd use data-binding to set up the array and so on.

Dean Harding
ya you were spot on. As soon as I added them in my createchildcontrols, it works as intended. I was sorta hoping I could add them dynamically...but that won't work so I guess I'll just have to show/hide them dynamically.I'll mark this as the answer, but if you can provide some suggestions as to how I can add them dynamically, that'd be swell :)Thanks.
Kyle
I've updated my answer with a bit of info about the Repeater control, which might help you to simplify things.
Dean Harding
A: 

I think FindControl only returns controls within an immediate container, so if you have them inside of say a DIV element or a table, then it will not find them. You can use a helper function similar to the following:

public static Control FindControl(Control start, string id)
{
  Control foundControl;
  if (start != null) 
  {
    foundControl = start.FindControl(id);
    if (foundControl != null) 
      return foundControl;

    foreach (Control c in start.Controls) 
    {
      foundControl = FindControl(c, id);
      if (foundControl != null) 
        return foundControl;
    }
  }
  return null;
}

You can then pass this or a specific container as a start parameter.

Alek Davis
That's only true if the `<div>` or `<table>` (etc) have `runat="server"`.
Dean Harding
A: 

What about something like this:

    int btnCount = 10;
    LinkButton[] btns = new LinkButton[btnCount];
    for (int i = 1; i <= btnCount; i++)
    {
        btns[i - 1] = new LinkButton(){
            Text = string.Format("{0} - Button", i) 
        };
    }
Seattle Leonard
A: 

As @Alek and @codeka mentioned, FindControl will only work once they have been added to a container, such as a Page object.

What you can do is instead of declaring them each as variables, add them to a List instead, like so:

var linkButtonList = new List<LinkButton>();
linkButtonList.Add(new LinkButton());
linkButtonList.Add(new LinkButton());
etc..

then you can loop through the List easily whenever you need to access all of the LinkButton controls:

foreach (var item in linkButtonList)
{
    // do something with the LinkButton here...
}
Jeff Schumacher
cool thanks. I ended up going with something close to this.thanks again.
Kyle