Trap Tab Key in Combobox

G

Guest

This is the 2nd time posting so sorry for duplications.
I am using VB.NT 2005 & a standard Combobox.
I've been wracking my brain over this problem for a over a month & cannot
seem to find a way to trap the pressing of a Tab Key when the focus is in a
Combobox. The KeyDown or KeyUp event for a combobox will not fire when the
tab key is pressed. The Keyup event will fire when the Tab key is used to tab
into the combo, however I want to trap it while the user intends to leave the
combo. If the user hits the Enter key while in the combo, I've trapped this
just fine & process the data
accordingly. But it's that dang Tab key that eludes me. I've tried to capture
it with the form's keyup/down events and they don't fire either when the tab
is pressed (they work fine when the other keys are pressed though).
So has anyone successfuly trapped a Tab key from within a combo box?
I've considerd other options like the lostfocus & leave events but by simply
leaving the control does not tell me the intent of the user; by hitting
either the enter or tab keys does tell me thier intent & i can process the
entry based on that intent.
The reason is that the user can either select from a list of Purchase Orders
& the grid will be resorted with the PO detail. However the user may enter a
valid PO number that is not already in the system. Generally a user will
either hit the <enter> key or the <tab> key to signify that they have entered
the PO they are looking for. If this PO is not a match to an existing PO I
want to give them the option to enter it at this point.
Thanks
Gary
 
M

Morten Wennevik [C# MVP]

Hi Gary,

You should be able to trap Tab if you override the Form's ProcessCmdKey method

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab && comboBox1.Focused)
{
// Put combobox logic here
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
 
B

Brian Schwartz

Check into the PreviewKeyDown event. The event args contains a property
called IsInputKey that you can set to true when you receive a tab.
 
G

Guest

Thanks, but I'm using VB.NET. Do yo have a suggested sample in VB? I'm not so
sure I can convert the C# syntax to VB.
Gary
 
G

Guest

Thanks for responding. After much research & effort with this & other
suggestions i found that the control.PreviewKeyDown event worked. So i am
using this. Thanks again.
Gary
 
M

Morten Wennevik [C# MVP]

Thanks, but I'm using VB.NET. Do yo have a suggested sample in VB? I'mnot so
sure I can convert the C# syntax to VB.
Gary

Morten Wennevik said:
Hi Gary,

You should be able to trap Tab if you override the Form's ProcessCmdKey method

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab && comboBox1.Focused)
{
// Put combobox logic here
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}

VB would be something like this

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean

If keyData = Keys.Tab And comboBox1.Focused Then
' Put combobox logic here
Return True
Else
Return MyBase.ProcessCmdKey(msg, keyData)
End If

End Function
 
G

Guest

Morton, thanks for the suggestion. However i was unable to find a way to
implement the suggestion. I found a KB article (320583) which seemed to
outline the details of your suggestion. I couldn't get the sample code to
work, I tried to follow the step by step instuctions to create the class
library but the suggested imports were rejected & when I made the imports
work, I then got errors in the Designer generated code which said it was
inconsistant with the imports. I do like the concepts but could not do
anything with them. I am sure that my level of experience plays a role in my
lack of success also. So thanks again.
Gary

 
M

Morten Wennevik [C# MVP]

Well, I have seen easier step by step documents, but an alternate way creating your own custom ComboBox is:

1) Create a new VB Project Windows Control Library
2) If it isn't open already open Solution Explorer from the View menu
3) Right click on UserControl1.vb and select "View Code"
4) Replace everything in the code file with

Public Class MyCombo

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, _
ByVal keyData As Keys) As Boolean
Const WM_KEYDOWN As Integer = &H100
Const WM_SYSKEYDOWN As Integer = &H104

If ((msg.Msg = WM_KEYDOWN) Or (msg.Msg = WM_SYSKEYDOWN)) Then
Select Case (keyData)
Case Keys.Tab
Me.Parent.Text = "TAB Captured"
Case Keys.Down
Me.Parent.Text = "Down Arrow Captured"
Case Keys.Up
Me.Parent.Text = "Up Arrow Captured"
Case Keys.Tab
Me.Parent.Text = "Tab Key Captured"
Case (Keys.Control Or Keys.M)
Me.Parent.Text = "<CTRL> + M Captured"
Case (Keys.Alt Or Keys.Z)
Me.Parent.Text = "<ALT> + Z Captured"
End Select
End If

Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class

4) The second leftmost button on the ToolBar on top of the Solution Explorer should be "Show All Files", click it. This will display some additional information about your project I have yet to figure out why is hidden in VB project (I recommend C#)
5) Click on the + sign to the left of UserControl1.vb (The + appears if you have selected "Show All Files")
6) Right click the UserControl1.Designer.vb and select "View Code"
7) Replace everything in the code file with

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class MyCombo
Inherits System.Windows.Forms.ComboBox

'UserControl1 overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub

End Class

8) Compile the project
9) Create a new Windows Application project
10) In Solution explorer right click the project and select "Add Reference..."
11) In the Add reference navigate to where the UserControl project is located and to the \bin\debug\ folder
12) Select the UserControl1.dll that should be there if you compiled theUserControl project successfully.
13) Right click on Form1.vb in solution explorer and select "View Code"
14) Replace all the code with

Public Class Form1
Public Sub New()
InitializeComponent()

Dim combo As New ???.MyCombo()
Me.Controls.Add(combo)
End Sub
End Class

15) Replace ??? with the Namespace the UserControl (MyCombo) is compiledwith. Alas this is another thing VB hides from you and C# displays. To see the Namespace in VB, right click the UserControl project and select Properties. In the Application TAB locate the "Root namespace:" fieldand use this instead of ??? in the Windows Application project.
16) Compile and run (F5) the Windows Application project. It should nowhave a ComboBox (Actually it's a MyCombo control). Selecting the ComboBox and pressing TAB causes MyCombo to notify its parent and set the parent's Text property to "TAB captured". Since the a Windows Form is the Parent, the text will be displayed in the titlae bar.




Morton, thanks for the suggestion. However i was unable to find a way to
implement the suggestion. I found a KB article (320583) which seemed to
outline the details of your suggestion. I couldn't get the sample codeto
work, I tried to follow the step by step instuctions to create the class
library but the suggested imports were rejected & when I made the imports
work, I then got errors in the Designer generated code which said it was
inconsistant with the imports. I do like the concepts but could not do
anything with them. I am sure that my level of experience plays a rolein my
lack of success also. So thanks again.
Gary
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top