面板与自动滚动重绘

时间:2016-06-29 07:51:51

标签: c# panel draw

我有一个以编程方式在其中添加面板的表单;

对于进入我的程序的每个任务,我添加一个标签和 进度条到面板,在前一个Y位置添加了30个像素Y.

但是当有时想要向下滚动时,面板会滚动, 位置成倍增加而不是确切位置。

记住,我检查并将Y位置写入控制台并看到Y位置正常,但面板没有正确显示

我认为问题是面板绘制方法, 但不知道如何解决它。

问题是任务26应该在25岁之后但不在正确的位置,尽管控制台我看到的位置是正确的。

添加控件的代码:

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

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

这与线程无关。添加控件时,当前滚动位置用于重新计算 有效 Location。奇怪的?是..

因此,原因可能是您在添加新控件时Panel 向下滚动。我不知道它发生在哪里,但这是一个很小的测试来证明这个问题:

enter image description here

看起来很熟悉吧?

我强制执行代码中的滚动,但在你的情况下,原因应该是相似的,应该是修复..

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

所以你的代码需要像这样设置Locations

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

(或者你会发现滚动是如何发生的并阻止它。)

答案 1 :(得分:0)

我发现在可滚动面板中添加第二个面板,将控件添加到第二个面板,并增加第二个面板的大小要容易得多。滚动位置的任何问题都不适用。

因此,请创建一个表单,添加一个按钮,添加一个panel1面板AutoScroll = true;,然后在第一个面板中添加另一个面板panel2(位置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);
}