具有自动滚动重绘功能的面板
Panel with auto scroll redraw
我有以编程方式在其中添加面板的表单;
对于进入我的程序的每个任务,我添加一个标签并
面板的进度条已将 30 像素 Y 添加到先前的 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();
}
}
这与线程无关。添加控件时,当前滚动位置用于重新计算 有效 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));
(或者你找出滚动是如何发生的并阻止它。)
我发现在可滚动面板内添加第二个面板、将控件添加到第二个面板并增加第二个面板的大小要容易得多。滚动位置的任何问题都不适用。
因此创建一个表单,添加一个按钮,添加一个面板 panel1
和 AutoScroll = true;
,然后在第一个面板(位置 0、0)内添加另一个面板 panel2
。
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);
}
我有以编程方式在其中添加面板的表单;
对于进入我的程序的每个任务,我添加一个标签并 面板的进度条已将 30 像素 Y 添加到先前的 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();
}
}
这与线程无关。添加控件时,当前滚动位置用于重新计算 有效 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));
(或者你找出滚动是如何发生的并阻止它。)
我发现在可滚动面板内添加第二个面板、将控件添加到第二个面板并增加第二个面板的大小要容易得多。滚动位置的任何问题都不适用。
因此创建一个表单,添加一个按钮,添加一个面板 panel1
和 AutoScroll = true;
,然后在第一个面板(位置 0、0)内添加另一个面板 panel2
。
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);
}