#vb.net #focus #custom-controls #lostfocus
#vb.net #фокус #пользовательские элементы управления #потерянный фокус
Вопрос:
У меня есть пользовательский элемент управления, который я создаю. Когда я нажимаю на него, он рисует пунктирную границу и накладывает на нее несколько выступов для изменения размера. Все это работает отлично. Теперь я хочу, чтобы при нажатии на него выбор был отменен. У меня уже есть переменная для настройки, выбрана она или нет, и 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
Ответ №1:
Попробуйте использовать события ввода и выхода для вашего пользовательского элемента управления.
GotFocus и LostFocus устарели в пользу Enter и Leave .
Обновить:
Поскольку вы наследуете от Control, вам, вероятно, следует переопределять свои события, а не обрабатывать их. Наведение курсора мыши также не обязательно захватывает фокус, поэтому вам, вероятно, тоже следует это проверить:
Пример:
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
Комментарии:
1. Но тогда он будет выбирать и отменять выбор, когда просто мышь уйдет вправо?
2. @DadeLamkins обновленный пример. Просматривая ваш код, я заметил, что вы не переопределяете события, что, вероятно, и следует делать.