Panel with auto scroll redraw

*爱你&永不变心* 提交于 2019-12-11 06:20:20

问题


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();                
            }
        }


回答1:


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.)




回答2:


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);
}


来源:https://stackoverflow.com/questions/38093489/panel-with-auto-scroll-redraw

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!