VB.NET使用AddHandler来检测鼠标在控件外单击是否不好?

VB.NET使用AddHandler来检测鼠标在控件外单击是否不好?,vb.net,Vb.net,我正在创建一组自定义控件,它们的一个功能是在激活时高亮显示。例如,当用户在文本框中单击时,文本框的边框将高亮显示一种颜色(或者它具有输入焦点),然后当用户在控件外单击时(包括在其他控件上),默认返回灰色 目前,我正在扫描父窗体,并在其中包含的每个控件(包括子控件)上使用AddHandler来查找用户在控件外单击的时间 Private Sub GatherChildren(Optional ByVal CTRL As Control = Nothing) For Each Child As

我正在创建一组自定义控件,它们的一个功能是在激活时高亮显示。例如,当用户在文本框中单击时,文本框的边框将高亮显示一种颜色(或者它具有输入焦点),然后当用户在控件外单击时(包括在其他控件上),默认返回灰色

目前,我正在扫描父窗体,并在其中包含的每个控件(包括子控件)上使用AddHandler来查找用户在控件外单击的时间

Private Sub GatherChildren(Optional ByVal CTRL As Control = Nothing)
    For Each Child As Object In CTRL.Controls
        If TypeOf Child Is MetroControl Then
            If DirectCast(Child, MetroControl).Controls.Count > 0 Then
                GatherChildren(Child)
            End If
            AddHandler Child.Click, ["LOSE FOCUS FUNCTION"]
        End If
    Next
End Sub
我很久以前在某个地方读到,添加处理程序会严重降低性能,而且在一个窗体上可能有很多控件的环境中。这可能会严重影响性能。所以我的问题是,AddHandler对性能有负面影响吗?如果是的话,有没有更有效的方法来解决我的问题


谢谢

如果不注销事件处理程序,这只是一种不好的做法。在子控件上,提供注册/取消注册事件处理程序的功能。可能会发生很多奇怪的行为(几乎总是很难调试):比如在同一个控件上多次注册事件处理程序。更不用说内存泄漏了

下面是我在生产代码中看到的一个示例。当然是为了演示而过度简化了

Public Class Form1

    Private Sub btnAddHandler_Click(sender As Object, e As EventArgs) Handles btnAddHandler.Click
        AddHandler btnClickMe.Click, Sub()
                                         txtLog.Text &= "Clicked!" & vbCrLf
                                     End Sub
        txtLog.Text &= "Added event handler." & vbCrLf
    End Sub

End Class
每次单击
btnAddHandler
btnClickMe
都会在单击txtLog时多次向其追加
“Clicked!”&vbCrLf
。这是一个非常简单的示例,但是如果您不小心,并且事件做了更重要的事情,那么它可能会成为一个有趣的调试日。;)

不,我不会说做你正在做的事是不好的做法。发送者是可以区分的,只要你不做像上面例子中那样疯狂的事情,你就可以了

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is TextBox Then
                With DirectCast(ctrl, TextBox)
                    AddHandler .GotFocus, AddressOf TextBox_GotFocus
                    AddHandler .LostFocus, AddressOf TextBox_LostFocus
                End With
            End If
        Next
    End Sub

    Private Sub TextBox_GotFocus(sender As Object, e As EventArgs)
        DirectCast(sender, TextBox).BackColor = Color.Azure
    End Sub

    Private Sub TextBox_LostFocus(sender As Object, e As EventArgs)
        DirectCast(sender, TextBox).BackColor = Color.DimGray
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        For Each ctrl As Control In Me.Controls
            If TypeOf ctrl Is TextBox Then
                With DirectCast(ctrl, TextBox)
                    RemoveHandler .GotFocus, AddressOf TextBox_GotFocus
                    RemoveHandler .LostFocus, AddressOf TextBox_LostFocus
                End With
            End If
        Next
    End Sub

End Class

此代码非常好。

如何操作
。单击
=
[“失焦功能”]
?逻辑上?[“失焦功能”]只是实际功能的替代品。我认为这样说更能说明问题。包含函数名并不重要,但MyMouseDown()是它的实际名称,我知道,我只是不认为点击事件会失去焦点。如果所有按钮/MetroControl都放在一个表单上,表单的mousedown事件不会证明存在不属于任何控件的点击/鼠标事件吗?如果用户点击了另一个控件,这只会证明用户点击了表单本身,表单事件不会激发。