【发布时间】:2016-07-12 12:57:22
【问题描述】:
我目前正在尝试将一些自定义控件添加到 winforms 中的面板。 每个控件都将停靠并构建类似“列表”的东西。 现在我正在尝试实现一个功能来选择/取消选择每个控件。 它工作正常,我的问题是它有时似乎很慢。 目前它在面板中大约有 50 个自定义控件。
modtable.Click += (s, e) =>
{
foreach (Control m in pnl_ucMods.Controls)
{
if(m is ModTableEntry)
{
if(m != modtable)
{
((ModTableEntry)m).BackColor = SystemColors.Control;
}
else if (m == modtable && m.BackColor == SystemColors.Control)
m.BackColor = SystemColors.ActiveCaption;
else
m.BackColor = SystemColors.Control;
}
}
};
每当我点击其中一个控件时,它都会改变背景颜色,第二次点击它会改变它,但只有在我再次点击之前等待一秒钟,它才会起作用。如果我点击快速,没有任何反应,我必须再次点击。 我知道 winforms 的设计不是为了拥有大量控件,而且我知道 foreach 需要一些时间来循环遍历所有控件,但也许这里有人对如何改进代码有一个小想法,也许可以解决这个问题。
tl;博士
单击面板中的自定义控件之一将更改其背景颜色。 (已选择)
所有其他控件也会改变背景颜色(取消选择)
如果点击的控件已经被选中,它将取消选择。
编辑: 一个小例子来测试这个问题。 只需新建一个项目,添加代码并调用即可。
private void addPanels()
{
Panel newPanel = new Panel();
newPanel.AutoScroll = true;
newPanel.Dock = DockStyle.Fill;
this.Controls.Add(newPanel);
for (int i = 0; i < 50; i++)
{
Panel childPanel = new Panel();
childPanel.Size = new Size(100, 30);
childPanel.Dock = DockStyle.Top;
childPanel.Click += (s, e) =>
{
foreach (Control p in newPanel.Controls)
{
if (p is Panel)
{
if (p != childPanel)
((Panel)p).BackColor = SystemColors.Control;
else if (p == childPanel && p.BackColor == SystemColors.Control)
p.BackColor = SystemColors.ActiveCaption;
else
p.BackColor = SystemColors.Control;
}
}
};
newPanel.Controls.Add(childPanel);
}
}
【问题讨论】:
-
@JohnCarpenter 基本上是的。应该可以单击每个控件。单击它会更改该面板中的所有其他控件以及被单击的控件。这不是正确的方法吗?有没有更好的办法?
-
您在哪里添加
Click事件处理程序?为什么不让它成为一个函数而不是一个 lambda?我想知道你是不是无意中多次添加了事件处理程序。 -
不到 1 毫秒。你的期望是什么?
-
@Backslash 如果你点击太快,那就是 DoubleClick。
-
代码中的另一个问题是您在事件处理程序委托中使用
childPanel。而是使用var sender = (Control)s;。这可能会导致一些问题,因为您在每个循环过程中都创建了新的子面板。
标签: c# winforms performance foreach