views:

293

answers:

3

What is a good way of finding the next and previous siblings of a control?

So for example if you have a panel with a number of buttons, textboxes, etc in it. Somewhere among those you have a user control which consists of a textbox and a button. When the button is clicked you for example want to find the name of the control that comes after this user control.

My goal is to create a user control that can swap its position with whatever comes before or after it (if there are any of course).

I know this should be kind of trivial, but I just can't seem to wrap my head around this one...=/

+1  A: 

It looks like you can call Controls.GetChildIndex(control) with your current control to get its index, then just index into the Controls collection to get the previous and next siblings.

Mike Hall
Could you provide an example? Preferably taking into account that it may or may not be the first or last control?
Svish
A: 
this.GetNextControl(Control,bool forward);

Retrieves the next control forward or back in the tab order of child controls.

EDIT:

Use Controls collection and its methods.

adatapost
Doh... how did I miss that one... But, does tab order stay the same when you reorder controls in a Controls collection? Or does it change accordingly?
Svish
A: 

This solution is rather specific for the FlowLayoutPanel case. Since it lays out the controls in the order that they appear in the controls collection, the trick is of course to find out the indices of the controls that should swap locations, and switch them:

private enum Direction
{
    Next,
    Previous
}

private void SwapLocations(Control current, Direction direction)
{
    if (current == null)
    {
        throw new ArgumentNullException("current");
    }
    // get the parent
    Control parent = current.Parent;
    // forward or backward?
    bool forward = direction == Direction.Next;
    // get the next control in the given direction
    Control next = parent.GetNextControl(current, forward);
    if (next == null)
    {
        // we get here, at the "end" in the given direction; we want to
        // go to the other "end"
        next = current;
        while (parent.GetNextControl(next, !forward) != null)
        {
            next = parent.GetNextControl(next, !forward);
        }
    }
    // get the indices for the current and next controls
    int nextIndex = parent.Controls.IndexOf(next);
    int currentIndex = parent.Controls.IndexOf(current);

    // swap the indices
    parent.Controls.SetChildIndex(current, nextIndex);
    parent.Controls.SetChildIndex(next, currentIndex);
}

Usage example:

private void Button_Click(object sender, EventArgs e)
{
    SwapLocations(sender as Control, Direction.Next);
}
Fredrik Mörk