我正在创建一个应用程序来安排不同的任务。这些是通过在面板上绘制矩形来显示的。这必须是响应。因此,我需要在每个尺寸变化上绘制并使其无效。当我达到规划面板的最大高度时,它会自动滚动。
问题是当我抓住滚动条并开始滚动一下时,当我释放滚动条时,我的整个应用程序和计算机都冻结了。
这很可能是因为每个小卷轴都会调用onpaint事件并堆叠起来,让应用程序挂起,直到它们全部完成。
现在我的问题是:我怎么能解决这个问题?可能通过多次调用paint事件,但是如何?
paint事件调用的方法:
private void panelPlanning_Paint(object sender, PaintEventArgs e)
{
for (int i = 0; i < userList.Count; i++)
{
Label temp = new Label();
temp.Text = userList[i].Text;
temp.Width = panelUsers.Width;
temp.Height = 50;
temp.BorderStyle = BorderStyle.FixedSingle;
temp.Location = new Point(0, i * 50);
temp.TextAlign = ContentAlignment.MiddleCenter;
panelUsers.Controls.Add(temp);
foreach (FullTask task in taskList)
{
if (task.AssignedTo == userList[i].Text && task.StartDate != "" && task.DueDate != "")
{
DateTime start = DateTime.ParseExact(task.StartDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
DateTime end = DateTime.ParseExact(task.DueDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
Brush brush;
if (task.Priority == Enums.priorities[2])
{
brush = Brushes.Yellow;
}
else if (task.Priority == Enums.priorities[1])
{
brush = new SolidBrush(Color.FromArgb(255, 0, 80, 123));
}
else
{
brush = Brushes.Red;
}
panelPlanning.CreateGraphics().FillRectangle(brush, new Rectangle((start.Subtract(dtPickerStart.Value).Days + 1) * labelDaysWidth, i * 50, (end.Subtract(start).Days + 1) * labelDaysWidth, 25));
}
}
}
}
答案 0 :(得分:4)
您正在为每个绘画事件添加新的Label控件。不要这样做:
// Label temp = new Label();
// temp.Text = userList[i].Text;
// temp.Width = panelUsers.Width;
// temp.Height = 50;
// temp.BorderStyle = BorderStyle.FixedSingle;
// temp.Location = new Point(0, i * 50);
// temp.TextAlign = ContentAlignment.MiddleCenter;
// panelUsers.Controls.Add(temp);
另外,使用参数提供的e.Graphics对象,而不是CreateGraphics,
答案 1 :(得分:0)
您必须在屏幕上跟踪哪些FullTask
实际必须显示。这可以通过查看Control.ClientRectangle并记住当前滚动位置来实现。
通过这种方式,从绘制的FullTasks
的所有集合中,您将只获得在屏幕上实际可见的任务子集,并仅绘制那些< / strong>即可。
这是处理可绘制工件的正确方法,这种工件在或多或少的所有绘图框架2D或甚至3D中实现。
如果某个元素被另一个元素覆盖(或者它的一部分被覆盖),那么也存在跟踪的概念,因此它将被“culed”,但在你的情况这似乎不是很重要。
还要注意添加控件的事实。不要那样做。如果FullTasks的数量很大,只需用Graphics对象绘制它们。
答案 2 :(得分:0)
以下代码行只能执行一次:
panelUsers.Controls.Add(temp);
您不断向temp
添加panelUsers control
的新实例。
答案 3 :(得分:0)
已经由@LarsTech描述,不要在paint事件中添加控件,并使用提供的Graphics对象而不是你自己的......
如果您仍然遇到性能问题,请考虑在更改内容时在位图上绘画,并且只在onPaint中将该位图绘制到屏幕上