繁体   English   中英

在VB.net中使用自定义控件处理焦点

[英]Handling Focus with Custom Controls in VB.net

我有一个正在创建的自定义控件。 当我单击它时,它会绘制一个虚线边框,并在其上放一些小块以调整大小。 所有这一切都完美。 现在我想要它,所以当我单击它时,它会取消选择。 我已经有了一个变量来设置是否被选中,以及用来绘制/清除它的子控件。 我只需要能够检测何时选择了其他选项或将其单击。

我尝试过的

我对此的第一个也是最好的解决方案是使用LostFocus事件,但是,通过自定义控件显然不会触发它。 据我所知,经过一些研究,自定义控件没有Focus事件,因为它们是自定义的并且可以更改(基本上,您必须自己实现focus事件)。

我的问题

是否有人解决焦点事件解决自定义控件单击问题的方法?

资料来源

这是我的控件的当前来源:

Imports System.Drawing.Drawing2D

Public Class wDOMElement
    Inherits Control

    Public selected As Boolean = False

    Private mdown As Boolean = False
    Private moffset As Point = Nothing

    Private nubs As New List(Of PictureBox)

    Private Sub wDOMElement_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
        MsgBox("test <-- DOES NOT SHOW!")
    End Sub

    Private Sub wDesignEditor_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        If mdown Then Return
        mdown = True
        moffset = MousePosition - Location
        selectME()
    End Sub

    Private Sub selectME()
        selected = True
        updateDraw()
        updateBorder()
        For Each v As PictureBox In nubs
            v.Show()
        Next
    End Sub

    Private Sub unselectME()
        selected = False
        updateBorder()
        updateDraw()
        For Each v As PictureBox In nubs
            v.Hide()
        Next
    End Sub

    Private Sub updateBorder()
        Using gfx As Graphics = Graphics.FromHwnd(Me.Handle)
            gfx.Clear(BackColor)
            If selected Then
                Dim blackPen As New Pen(Brushes.Black)
                blackPen.DashStyle = DashStyle.Dot
                gfx.DrawRectangle(blackPen, 4, 4, Width - 9, Height - 9)
            End If
        End Using
    End Sub

    Private Sub updateDraw()
        'Needs to be overriden
    End Sub

    Private Sub configureFirstSelection()
        Using gfx As Graphics = Graphics.FromHwnd(Me.Handle)
            Dim blackPen As New Pen(Brushes.Black)
            blackPen.DashStyle = DashStyle.Dot
            gfx.DrawRectangle(blackPen, 4, 4, Width - 9, Height - 9)
            'Top Handle
            placeHandle(My.Resources.Handle, CInt(Width / 2 - 3), CInt(0), New Point(0, 1), New Point(0, -1), Cursors.SizeNS, AnchorStyles.Top)
            'Bottom Handle
            placeHandle(My.Resources.Handle, CInt(Width / 2 - 3), CInt(Height - 7), New Point(0, 0), New Point(0, 1), Cursors.SizeNS, AnchorStyles.Bottom)
            'Left Handle
            placeHandle(My.Resources.Handle, CInt(0), CInt(Height / 2 - 3), New Point(1, 0), New Point(-1, 0), Cursors.SizeWE, AnchorStyles.Left)
            'Right Handle
            placeHandle(My.Resources.Handle, CInt(Width - 7), CInt(Height / 2 - 3), New Point(0, 0), New Point(1, 0), Cursors.SizeWE, AnchorStyles.Right)
            'Top Left Handle
            placeHandle(My.Resources.Handle, CInt(0), CInt(0), New Point(1, 1), New Point(-1, -1), Cursors.SizeNWSE, AnchorStyles.Top + AnchorStyles.Left)
            'Top Right Handle
            placeHandle(My.Resources.Handle, CInt(Width - 7), CInt(0), New Point(0, 1), New Point(1, -1), Cursors.SizeNESW, AnchorStyles.Top + AnchorStyles.Right)
            'Bottom Left Handle
            placeHandle(My.Resources.Handle, CInt(0), CInt(Height - 7), New Point(1, 0), New Point(-1, 1), Cursors.SizeNESW, AnchorStyles.Bottom + AnchorStyles.Left)
            'Bottom Right Handle
            placeHandle(My.Resources.Handle, CInt(Width - 7), CInt(Height - 7), New Point(0, 0), New Point(1, 1), Cursors.SizeNWSE, AnchorStyles.Bottom + AnchorStyles.Right)
        End Using
    End Sub

    Private Sub placeHandle(ByVal pic As Image, ByVal x As Integer, ByVal y As Integer, ByVal mov As Point, ByVal siz As Point, ByVal cur As Cursor, ByVal ancr As AnchorStyles)
        Dim nPB As New PictureBox
        nPB.SizeMode = PictureBoxSizeMode.AutoSize
        nPB.Image = pic
        nPB.Location = New Point(x, y)
        nPB.Cursor = cur
        nPB.Visible = False
        nPB.Anchor = ancr
        nPB.Parent = Me
        Dim md As Boolean = False
        Dim lpos As Point = Nothing
        Dim moveClock As New Timer
        moveClock.Interval = 1
        moveClock.Enabled = False
        AddHandler nPB.MouseDown, Sub()
                                      md = True
                                      lpos = MousePosition
                                      moveClock.Start()
                                  End Sub

        AddHandler moveClock.Tick, Sub()
                                       If md Then
                                           Dim nX As Integer = (MousePosition.X - lpos.X) * mov.X
                                           Dim nY As Integer = (MousePosition.Y - lpos.Y) * mov.Y
                                           Dim nWidth As Integer = (MousePosition.X - lpos.X) * siz.X
                                           Dim nHeight As Integer = (MousePosition.Y - lpos.Y) * siz.Y
                                           Left += nX
                                           Top += nY
                                           Width += nWidth
                                           Height += nHeight
                                           lpos = MousePosition
                                           updateDraw()
                                           updateBorder()
                                       End If
                                   End Sub
        AddHandler nPB.MouseUp, Sub()
                                    md = False
                                    moveClock.Stop()
                                End Sub
        nubs.Add(nPB)
    End Sub

    Private Sub wDesignEditor_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        If mdown Then
            Location = MousePosition - moffset
        End If
    End Sub

    Private Sub wDesignEditor_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
        mdown = False
    End Sub

End Class

尝试对您的自定义控件使用Enter和Leave事件。

GotFocus和LostFocus已经过时,转而支持Enter和Leave。

更新:

由于您是从Control继承的,因此您可能应该覆盖事件,而不是处理它们。 MouseDown也不一定会吸引焦点,因此您也应该检查一下:

例:

Public Class ControlEx
  Inherits Control

  Protected Overrides Sub OnEnter(e As EventArgs)
    MyBase.OnEnter(e)
    MessageBox.Show("Hello")
  End Sub

  Protected Overrides Sub OnLeave(e As EventArgs)
    MyBase.OnLeave(e)
    MessageBox.Show("Good-bye")
  End Sub

  Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
    If Me.Enabled AndAlso Not Me.Focused Then
      Me.Focus()
    End If

    MyBase.OnMouseDown(e)
  End Sub

End Class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM