【问题标题】:Panel with auto scroll redraw具有自动滚动重绘功能的面板
【发布时间】:2016-06-29 07:51:50
【问题描述】:

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

对于进入我的程序的每个任务,我添加一个标签和 面板的进度条在之前的 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();                
            }
        }

【问题讨论】:

  • @MickyD 我编辑了我的问题并添加了代码
  • @MickyD 不,我没有任何特殊图纸。只是您在上图中看到的控件。
  • 那么,我应该如何解决这个问题?
  • 我不能这样做,因为需要使用 InvokeRequired 从多个线程更新标签和进度条值

标签: c# panel draw


【解决方案1】:

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

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

看起来很眼熟,对吧?

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

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

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

【讨论】:

  • 所以当我想重绘时,我必须为每个按钮计算 111px 吗?如果 value!=25px 做这个工作?我应该在面板的滚动事件中重绘每个控件?
  • 不!只需使用答案底部的 3 行,即在添加时将 AutoScrollPosition.Y 添加到所有三个控件的 y 值中。一旦它们被放置,就不需要进一步的操作。 111 只是滚动如何弄乱位置的一个示例,问题仅在(不知何故)添加控件的过程中滚动时出现..
【解决方案2】:

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

因此,创建一个表单,添加一个按钮,添加一个面板 panel1AutoScroll = 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);
}

【讨论】:

  • 不知道它是如何工作的,但 imo 这并不比一开始就设置好位置更容易......
  • @Taw 这样您就不必考虑任何滚动位置。如果您不确定它是如何工作的,那么也许您可以尝试一下,自己看看。
  • 啊,对不起,我没有完全理解你的想法。所以,是的,我想它会起作用。但是在确实不需要时添加一个额外的面板似乎仍然不是“容易得多”。请注意,我的解决方案只包含对 y 位置的一个附加值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 2020-08-21
  • 1970-01-01
相关资源
最近更新 更多