views:

239

answers:

3

I have a place in my code where I am dynamically adding controls to a Top-Down arranged FlowLayoutPanel. I need the controls to appear in a certain order so what I am doing everytime is clearing the FlowLayoutPanel.Controls collection and then adding each child control in the order I want them to appear. My code does this:

private void arrangement1()
{
    flowLayoutPanel1.Controls.Clear();
    flowLayoutPanel1.Controls.Add(control1);
    flowLayoutPanel1.Controls.Add(control2);
    flowLayoutPanel1.Controls.Add(control3);
}

Most of the time this works great. However, there is one specific control that does not maintain it's position in the control collection when adding other controls after it. For instance in the following code segment:

private void arrangement2()
{
    flowLayoutPanel1.Controls.Clear();
    flowLayoutPanel1.Controls.Add(control1);
    flowLayoutPanel1.Controls.Add(movingControl);
    //movingControl current is at index = 1 in Controls.
    flowLayoutPanel1.Controls.Add(control2);
    //control2 is now at index = 1, movingControl got bumped to index = 2 in Controls.
    flowLayoutPanel1.Controls.Add(control3);
    //control3 is now at index =2, movingControl got bumped to index = 3 in Controls.
}

This only happens the first time movingControl is added to Controls. If I go back and call arrangement1 and then arrangement2 a second time. The controls will appear the in intended order of:

  • control1
  • movingControl
  • control2
  • control3

This seems to be a bug in the code for Controls.Add. Either that or the documentation for .Add's behaviour is incomplete as it doesn't always add to the end of the collection. Does anyone have any insight into why this occurs. The obvious "fix" is to just call:

arrangement2();
arrangement1();
arrangement2();

However, that seems like a very poor solution to some other underlying problem.

Thanks in advance for the help!

EDIT: Note that each of these controls is a member of a custom view class so they persist after the Controls collection is Cleared. However, these controls are not stored in any sort of ordered collection. They are just members of this custom class. The code shown above works correctly as shown. However, in the context of my GUI program it has the described erroneous behaviour. I would post more code if I had any idea what would be helpful but there is a lot of code that touches these peices. This is all of the code that executes for the described action.

What I'm really looking for is what possible scenarios cause a Controls.Add to Insert a control not at the last index of the collection. Specifically after a call to Clear() and with NO Remove() calls.

+1  A: 

First running Arrangement1 gives me: control1 control2 control3

Running arrangement2 gives me: control1 movingcontrol control2 control3

Your code, pure as it is posted, works for me.

However, recently i encountered a similar problem. I was holding the controls in a list, then itterating through this to add them to the flowlayout. Removing a single item from the list, then adding a new control would not insert the new control at the end, it would replace the vacant spot left by the deleted item.

So in summary, i suspect it's something you haven't posted, possibly where you store the controls themselves? do you store them in an array or a List?

Lily
As stated above. These controls are members of a custom view class which is manipulated via a view controller class. I would post more code if I could narrow down what code to post. I guess I'm looking for insight into what could possibly be causing an Add to Insert at an index other than the last index of the Collection, specifically after a Clear and not any Removes.
TJ_Fischer
I understand, it must be difficult for you to simplify the code to formulate it here, into a comprehensible question.The type in which you store the control instances can affect the order. For instance, in a List or Dictionary, there is no notion of "order" or sorting. If it's in an array then the position in the array is the order. If however, the user can remove and re-add things one-by-one, then you will have the same case i had in my initial reply.
Lily
A: 

Dump question. Is it possible, that some variables aka. "movingControl", "control2", etc. point to the same object/reference and you try to add the same object multiple times?

Here´s some code do display what i mean.

Control control1 = new Control();
Control control2 = new Control();
Control movingControl;

public void Dummy() {
  movingControl = control2;

  arrangement2();
}
Jehof
No that's not the case. Each control reference only ever has one value and that is a unique instance of some user control. Thanks for the thought.
TJ_Fischer
A: 

Would it not be easier to just toggle the visibilty of movingControl?

But I guess that answer is based on your example such that if more rearranging is going on then this may not apply.

In conjunction with visibility toggling, you could also look into using ControlCollection.SetChildIndex() instead which seems more appropriate and seems more likely to produce a smoother re-ordering.

Reddog