tags:

views:

36

answers:

2

Is there a way to find the previous and next sibling controls in an ASP.net form from code-behind, similar to findControl()?

Sometimes you don't want to assign an ID to a control just so you can do a parent().findControl("ID") in order to find it. I'm tired of coming up with IDs when all I could do is previousControl() or something (a la jQuery).

This would also be useful in situations where you write a general function in order to address several controls which have a similar layout and don't want to address them one by one.

Thanks for any suggestions.

+1  A: 

I don't think there is a built in function like that, but it is very easy to extend the Control class and add methods to it like so:

public static Control PreviousControl(this Control control)  
{
   for(int i=0; i<= control.Parent.Controls.Count; i++)
      if(control.Parent.Controls[i].Id == control.Id)
         return control.Parent.Controls[i-1];
}

Of course a bit more handling needs to be done here (if there is no previous control or other scenarios) but i think you get the picture of how this could be done.

After writing this method you can call it like

Control textBox1 = textBox2.PreviousControl();
Atzoya
Thank you for your suggestion, but it has 2 issues: first you assume that the original control must have an ID, which is not good in my case. Second, your function is going to match the Literal controls ASP.net generates in order to output your static HTML. That's a no go. See my own solution for a version that addresses all that.
md1337
+2  A: 

For posterity, here is the function I ended up writing. Works very well (tested in a real project):

    public static Control PreviousControl(this Control control)
    {
        ControlCollection siblings = control.Parent.Controls;
        for (int i = siblings.IndexOf(control) - 1; i >= 0; i--)
        {
            if (siblings[i].GetType() != typeof(LiteralControl) && siblings[i].GetType().BaseType != typeof(LiteralControl))
            {
                return siblings[i];
            }
        }
        return null;
    }

To be used like this:

Control panel = textBox.PreviousControl();

and for next control:

    public static Control NextControl(this Control control)
    {
        ControlCollection siblings = control.Parent.Controls;
        for (int i = siblings.IndexOf(control) + 1; i < siblings.Count; i++)
        {
            if (siblings[i].GetType() != typeof(LiteralControl) && siblings[i].GetType().BaseType != typeof(LiteralControl))
            {
                return siblings[i];
            }
        }
        return null;
    }

The advantage of this solution over that of Atzoya is that, first, you don't need the original control to have an ID since I do the search based on instance. Second, you have to know that ASP.net generates several Literal controls in order to render your static HTML in between your "real" controls. That's why I skip them, or you will keep matching junk. Of course the downside of this is you can't find a control if it's a Literal. This limitation was not a problem in my use.

md1337