Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Thursday, November 20, 2014 4:33 PM
I have been researching for a while on this subject and I am getting a little bit here and there, but I can't seem to get this to work. I have a base form in my project that Inherits the System.Windows.Forms.Form object. This generic form has the KeyPreview property and I can set it to true when the form is create. No problem there, however, I have a UserControl base object that is hosted in this window. It Inherits Windows.Forms.UserControl. From this base user control, I can create specific controls I need from this base user control. So my form hosts one or more user controls.
Here is the problem. I can set the keyPreview to true on the form, but not the user control. I need to have the enter key act as a tab key until the control focus is a button, to which the enter button needs to act as normal and do a button click. I also need the arrow keys to act as a tab to move focus through the controls where the up and back arrow moves the focus back to the previous control, and down and right move to the next control.
I noticed there is no KeyPreview on the UserControl object and from what I read that is because the user control is a container to host other controls so I am stuck.
The reason for this behavior is the user entering data usually enter numeric data and only use the keypad of the keyboard and it slows up data entry to enter data then hit tab or mouseclick to the next field.
Thanks.
All replies (3)
Friday, November 21, 2014 10:01 AM ✅Answered
I prefer using the way suggested in https://social.msdn.microsoft.com/Forums/vstudio/en-US/3f3bbba5-db71-4b91-9586-dbea57ed4d7f/net-usercontrol-keypress-event .
Write this bit of code in the user control and then drag the control to the form.Put in a
debug statement in the line of code in the control and when you press a key on the user control
the debug statement will be hit.
Protected Overrides Function ProcessKeyPreview(ByRef m As Message) As Boolean
//Process the message to look for the key which was pressed.You will find lots of
//example by googling Return MyBase.ProcessKeyPreview(m) End Function
remember make the reply as answer and vote the reply as helpful if it helps.
Monday, November 24, 2014 3:24 PM ✅Answered
Thanks all. After more searching over the weekend, I ran across the ProcessCmdKey which I was able to override to get what I needed. Here is the code:
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
'This is needed for the user control to capture the keys before bubbling them up. This will allow the controls to act with key commands
'first. This will substitue the Enter and arrow keys for a tab or alt+tab functionality to move the cursor between tap stop controls in the user control.
Select Case keyData
Case ModifierKeys.Enter
Windows.Forms.SendKeys.Send("{TAB}")
Case ModifierKeys.Down
Windows.Forms.SendKeys.Send("{TAB}")
Case ModifierKeys.Up
Windows.Forms.SendKeys.Send("+{TAB}")
Case ModifierKeys.Right
Windows.Forms.SendKeys.Send("{TAB}")
Case ModifierKeys.Left
Windows.Forms.SendKeys.Send("+{TAB}")
Case Else 'ignore the keys and pass the message up
MyBase.ProcessCmdKey(msg, keyData)
End Select
MyBase.ProcessCmdKey(msg, keyData)
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Saturday, November 22, 2014 1:44 AM
I didn't test this in the capacity that you want to use it. The code is for UserControl1. It has Buttons1 to 3 on it.
I placed one Button on the Form and two of the user controls on the Form.
If Button1 on the Form has focus and you select a left or right arrow key then immediately the focus goes to the first Button on the top user control (the first one added to the Form). Then selecting left or right arrow keys focuses only the Buttons in the top user control.
The tab key can be used to move from the Button on the Form to each UserControl then back to the Button on the Form.
If you tab to the second UserControl (the bottom one) then arrow keys will only focus its buttons.
I'm not sure that is what you want. Also I suppose better code could be provided in the UserControls code for doing whatever you desire.
There's a sub in the UserControl that is almost the same as the sub Risa displays in her post. I use that sub in a Form if I want to get any key selected on the keyboard regardless of the control that has focus when the key is selected. And I retrieved that sub from an app which in the Form Load event has KeyPreview set to true which maybe is not necessary. It doesn't seem necessary in the UserControl.
EDIT: It's also probable the logic for the If statements to reset the variable Counter are not in the correct location of the sub. Or prior to Counter += or -= 1 the next Nr should be known ahead of time to set the counter then so it can't go negative or more than the indexes in the List(Of Control). As it seems to me looking at the code that an error could occur if a certain Button was focused and you selected the arrow key that would move in the opposite direction perhaps. As I said I didn't really test this other than to focus the buttons but not forwarding and reversing direction at each location to see what may occur.
Option Strict On
Public Class UserControl1
Dim MyControls As New List(Of Control)
Private Sub UserControl1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each Ctl As Control In Me.Controls
MyControls.Add(Ctl)
Next
End Sub
Dim Counter As Integer = 0
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If Counter < 0 Then Counter = MyControls.Count - 1
If Counter > MyControls.Count - 1 Then Counter = 0
If keyData = Keys.Left Then
GetNextControl(MyControls(Counter), False)
Counter -= 1
ElseIf keyData = Keys.Right Then
GetNextControl(MyControls(Counter), True)
Counter += 1
End If
Return Nothing
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MessageBox.Show("Btn1")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
MessageBox.Show("Btn2")
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
MessageBox.Show("Btn3")
End Sub
End Class
La vida loca