0

我创建了一个表单,它有一个选项卡式控件,可以动态地将用户控件添加到每个选项卡中,并在表单底部有一个 StatusStrip。当应用程序启动时,用户控件会根据安全性加载到选项卡中,并至少加载 1 个选项卡。在 StatusStrip 上,有两个 ToolStripComboBoxes、2 个 ToolStripButtons、1 个 ToolStripLabel 和 1 个 ToolStripStatusLabel。一切都很好并且可以正常工作。

当用户按下两个按钮之一时,我被要求弹出 MonthCalendar 。这是我用来执行此操作的代码:

If IsNothing(theCal) Then
    theCal = New MonthCalendar
    AddHandler theCal.DateSelected, AddressOf theCalDateSelected
    AddHandler theCal.LostFocus, AddressOf theCalLostFocus
    AddHandler theCal.GotFocus, AddressOf theCalLostFocus
    theCal.Parent = Me
    theCal.Top = StatusStripMain.Top - theCal.Height
    theCal.Left = ComboBoxAvailableLegDay.Bounds.X
    theCal.Anchor = AnchorStyles.Bottom + AnchorStyles.Left
    theCal.Show()
    theCal.BringToFront()
    theCal.Focus()
Else
    Me.Controls.Remove(theCal)
    theCal = Nothing
End If

theCal 在表单类的顶部被定义为 Protected。因此,按下按钮将创建 MonthCalendar 并正确定位它,如果它不存在,如果它存在,则将其删除。这没有问题。

我的问题是 theCal 永远不会触发 GotFocus 或 LostFocus。我有如下定义的过程 theCalLostFocus 并且它从不抛出异常。我可以在 throw 处设置一个断点,而代码永远不会到达那个点。

Private Sub theCalLostFocus(ByVal sender As Object, ByVal e As EventArgs)
    Throw New NotImplementedException
End Sub

单击 Cal 上的日期将调用 CalDateSelected 过程,但单击窗体的任何其他区域不会触发 CalLostFocus。由于用户可能不想选择日期并且我不想强迫他们必须按下按钮来移除 theCal,我希望能够在失去焦点时移除 theCal。任何人都知道为什么会发生这种情况并且有人有解决方案吗?

谢谢。-NCGrimbo

4

1 回答 1

1

我对焦点事件不会触发并不感到惊讶,因为您在将处理程序插入可视树之前添加了处理程序。尝试在调用 show() 之后添加处理程序。或者可能在加载的事件处理程序中。请注意,由于您请求焦点,因此每次都会调用焦点事件处理程序。

Rq :正如它所写的那样,您的代码存在内存泄漏,因为您在清除 theCal 时没有删除事件处理程序,因此由于保留了对 theCal 的引用,因此 theCal 和事件处理程序都不会被清除,这会导致内存泄漏(周期性参考)。

于 2012-08-23T18:53:23.590 回答