Обработка фокуса с помощью пользовательских элементов управления в VB.net - PullRequest
0 голосов
/ 03 ноября 2011

У меня есть пользовательский элемент управления, который я создаю.Когда я нажимаю на нее, она рисует пунктирную границу и добавляет к ней несколько выступов для изменения размера.Это все работает отлично.Теперь я хочу, чтобы, когда я щелкаю по нему, он отменяет выбор.У меня уже есть переменная для установки, если она выбрана или нет, и подпрограммы для ее рисования / очистки.Я просто должен быть в состоянии определить, когда что-то выбрано или оно отключено.

То, что я пробовал

Мое первое и лучшее решение для этогодолжен был использовать событие 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

1 Ответ

3 голосов
/ 04 ноября 2011

Попробуйте использовать события 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
...