MD'*_*D's 3 .net c# events winforms
以下是我的代码,用于处理表单中可用的所有文本框的gotfocus和lostfocus事件.
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
if (c is TextBox)
{
c.GotFocus += new System.EventHandler(this.txtGotFocus);
c.LostFocus += new System.EventHandler(this.txtLostfocus);
}
}
}
private void txtGotFocus(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
if (tb != null)
{
tb.BackColor = Color.Silver;
tb.BorderStyle = BorderStyle.FixedSingle;
}
}
private void txtLostFocus(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
if (tb != null)
{
tb.BackColor = Color.White;
tb.BorderStyle = BorderStyle.Fixed3D;
}
}
Run Code Online (Sandbox Code Playgroud)
它可以在第一个文本框中正常工作,但是当我按Tab键转到下一个文本框时,它将重复调用这两个事件,文本框的行为就像闪烁一样.一段时间后错误信息显示在代码中:
在类型为"System.Windows.Forms!System.Windows.Forms.NativeMethods + WndProc :: Invoke"的垃圾收集委托上进行了回调.这可能会导致应用程序崩溃,损坏和数据丢失.将委托传递给非托管代码时,托管应用程序必须将它们保持活动状态,直到确保它们永远不会被调用.
代码有什么问题?有什么解决方案吗?
Han*_*ant 21
c.LostFocus += new System.EventHandler(this.txtLostfocus);
Run Code Online (Sandbox Code Playgroud)
LostFocus是一个危险的事件,Control.LostFocus的MSDN Library文章警告这一点,强烈建议使用Leave事件.您可以在设计器中看到这一点,在表单上放置一个TextBox,然后单击"属性"窗口中的闪电图标.请注意GotFocus和LostFocus事件都不可见.您必须改为使用Enter和Leave事件.
关于这里发生了什么的一些背景知识.您的程序会因为分配BorderStyle属性而爆炸.这是一个"困难"属性,它会影响窗口的样式标志,即传递给本机CreateWindowEx()函数的标志.因此,更改边框样式需要Winforms再次创建本机窗口.这就是导致你看到闪烁的原因,文本框被破坏并重新创建,然后重新绘制.你看到了.
但是它具有超出闪烁的副作用,它还会导致低级别的GotFocus和LostFocus事件被触发.因为被破坏的窗户当然也失去了焦点.由于LostFocus事件处理程序再次更改BorderStyle,因此会在程序中进行非常差的交互,从而迫使Winforms再次重新创建窗口.并触发GotFocus事件,您再次更改BorderStyle.这反复重复,你看到文本框快速闪烁.这不会无休止地进行,在创建窗口10,000次之后,操作系统会拔出插件并且不会让程序再创建另一个.窗口程序的严重崩溃是结果.
对于Enter和Leave事件没有问题,它们不能从低级Windows通知中工作,因此在重新创建文本框窗口时不要触发.你只能通过不改变BorderStyle属性来摆脱一次性的闪烁,如果它仍然困扰你.
| 归档时间: |
|
| 查看次数: |
7919 次 |
| 最近记录: |