[英]Handling Focus with Custom Controls in VB.net
I have a custom control I'm creating. 我有一个正在创建的自定义控件。 When I click on it, it draws a dotted border and puts some nubs on it for resizing.
当我单击它时,它会绘制一个虚线边框,并在其上放一些小块以调整大小。 This all works perfectly.
所有这一切都完美。 Now I want it so when I click off of it, it deselects.
现在我想要它,所以当我单击它时,它会取消选择。 I already have a variable to set up if it's selected or not and subs to draw/clear it.
我已经有了一个变量来设置是否被选中,以及用来绘制/清除它的子控件。 I just have to be able to detect when something else is selected or it gets clicked off of.
我只需要能够检测何时选择了其他选项或将其单击。
What I've Tried 我尝试过的
My first and best solution to this was to use the LostFocus
event, but, by custom control apparently won't let it fire. 我对此的第一个也是最好的解决方案是使用
LostFocus
事件,但是,通过自定义控件显然不会触发它。 After some research, as far as I know, custom controls don't have Focus events because they are custom and could be changed (basically, you have to implement the focus events yourself). 据我所知,经过一些研究,自定义控件没有Focus事件,因为它们是自定义的并且可以更改(基本上,您必须自己实现focus事件)。
My Question 我的问题
Does anybody have a solution to either implement the focus events or a way to handle off clicking for custom controls? 是否有人解决焦点事件或解决自定义控件单击问题的方法?
Sources 资料来源
Here is my controls current source: 这是我的控件的当前来源:
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
Try using the Enter and Leave events for your custom control. 尝试对您的自定义控件使用Enter和Leave事件。
GotFocus and LostFocus have sort of been deprecated in favor of Enter and Leave. GotFocus和LostFocus已经过时,转而支持Enter和Leave。
Update: 更新:
Since you are inheriting from Control, you should probably be overriding your events, not handling them. 由于您是从Control继承的,因此您可能应该覆盖事件,而不是处理它们。 MouseDown won't necessarily grab the focus either, so you should probably check that, too:
MouseDown也不一定会吸引焦点,因此您也应该检查一下:
Example: 例:
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.