Reputation: 1499
I have form that programmatically add a panel in it;
For each task coming in to my program, I add a label and progress bar to panel which have 30 pixel Y added to previous Y position.
But when panel get scrolls sometimes when want to scroll down, positions multiplied and not in their exact position.
Remember, I checked and written Y positions to console and saw that Y position is ok, but panel does not show it correctly
I think problem is for panel draw method, but don't know how to fix it.
Problem is that task 26 should come just after 25 but not in correct position, despite of console I've seen position is correct.
code to add controls:
private static void AddTaskControls(int taskId)
{
Label lbl = new Label();
lbl = new Label();
lbl.Name = "lbl" + taskId.ToString();
lbl.Text = "Task " + taskId.ToString() + ":";
lbl.Width = 57;
lbl.Height = 13;
lbl.Location = new Point(0, 25 + (taskId) * 30);
ProgressBar pr = new ProgressBar();
pr = new ProgressBar();
pr.Name = "pr" + taskId.ToString();
pr.Width = 180;
pr.Height = 23;
pr.Location = new Point(50, 20 + (taskId) * 30);
Label lbl2 = new Label();
lbl2.Name = "lbl" + taskId.ToString() + "List";
lbl2.Text = "Starting " + taskId.ToString() + "";
lbl2.Width = 200;
lbl2.Height = 13;
lbl2.Location = new Point(230, 25 + (taskId) * 30);
//Console.WriteLine(lbl2.Location.Y + "taskid:"+taskId);
if (panel1.InvokeRequired)
{
AddTaskControllsCallback t = new AddTaskControllsCallback(AddTaskControls);
panel1.BeginInvoke(t, new object[] { taskId });
}
else
{
panel1.Controls.Add(lbl);
panel1.Controls.Add(pr);
panel1.Controls.Add(lbl2);
pr.BringToFront();
}
}
Upvotes: 1
Views: 1002
Reputation: 22945
I've found that it is a lot easier to add a second panel inside the scrollable panel, add the controls to that second panel, and increase the size of the second panel. Any problems with scrolling position do not apply then.
So create a form, add a button, add a panel panel1
with AutoScroll = true;
, and add another panel panel2
inside the first panel (with location 0, 0).
private void button1_Click(object sender, EventArgs e)
{
// lets add a few buttons..
for (int i = 0; i < 25; i++)
{
Button btn = new Button();
btn.Top = i * 25;
panel2.Controls.Add(btn); // Add to panel2 instead of panel1
}
// Recalculate size of the panel in the scrollable panel
panel2.Height = panel2.Controls.Cast<Control>().Max(x => x.Top + x.Size.Height);
panel2.Width = panel2.Controls.Cast<Control>().Max(x => x.Left + x.Size.Width);
}
Upvotes: 0
Reputation: 54433
This has nothing to do with threading. When adding controls the current scroll position is used to re-calculate the effective Location
. Weird? Yes..
So the reason probably is that your Panel
scrolls down while you are adding new controls. I don't see where it happens but here is a tiny test to demonstrate the problem:
Looks familiar, right?
I enforce the scrolling in the code but in your case the reason should be similar, as should be the fix..
private void button20_Click(object sender, EventArgs e)
{
// lets add a few buttons..
for (int i = 0; i < 20; i++)
{
Button btn = new Button();
btn.Top = i * 25;
btn.Parent = panel2;
}
// ..now let's enforce a scoll amount of 111 pixels:
panel2.AutoScrollPosition = new Point(panel2.AutoScrollPosition.X,
-panel2.AutoScrollPosition.Y + 111);
// ..and add a few more buttons..
for (int i = 20; i < 40; i++)
{
Button btn = new Button();
btn.Top = i * 25; // not good enough!
// btn.Top = i * 25 + panel2.AutoScrollPosition.Y; // this will fix the problem!
btn.Parent = panel2;
}
}
So your code needs to set the Locations
like this:
lbl.Location = new Point(0, 25 + (taskId) * 30 + panel1.AutoScrollPosition.Y);
..
pr.Location = new Point(50, 20 + (taskId) * 30 + panel1.AutoScrollPosition.Y));
..
lbl2.Location = new Point(230, 25 + (taskId) * 30 + panel1.AutoScrollPosition.Y));
(Or you find out how the scrolling happens and prevent it.)
Upvotes: 1