0

我有一个正在创建的自定义控件。当我单击它时,它会绘制一个虚线边框并在其上放置一些小块以调整大小。这一切都完美无缺。现在我想要它,所以当我单击它时,它会取消选择。如果它被选中,我已经有一个变量要设置,并且 subs 来绘制/清除它。我只需要能够检测到什么时候选择了其他东西或者它被点击了。

我试过的

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

我的问题

有没有人有解决方案来实现焦点事件处理点击自定义控件的方法?

来源

这是我的控件当前来源:

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
4

1 回答 1

3

尝试为您的自定义控件使用 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
于 2011-11-03T22:44:04.047 回答