Обработка фокуса с помощью пользовательских элементов управления в 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
1 ответ
Попробуйте использовать события 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