< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
I have a complex class full of controls including a Rich Text box and a regular textbook. The class is designed as a tab page to be added once or multiple time to a tab control. This class inherits Windows.Forms.Form.
When the page is added, I want the cursor to be in the ordinary text box.
It isn’t. There is a prescribed way to do this:
To programmatically click the right mouse button
1. Create a MouseEventArgs whose Button property is set to the System.Windows.Forms.MouseButtons.Right value.
2. Call the OnMouseClick method with this MouseEventArgs as the argument.
This is what I’ve done.
Private Sub t_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles t.ControlAdded
gbControls.TabIndex = 0 ' container for the textbox
tb.TabIndex = 0 ' taborder is 0
Dim a As New MouseEventArgs(Windows.Forms.MouseButtons.Left, 1, 8, 8, 0)
tb_MouseClick(tb, a)
End Sub
Private Sub tb_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tb.MouseClick
OnMouseClick(e)
End Sub
I am able to execute within the class after the tabpage is added via the Tabpage’s (named t) ControlAdded event. This all works. Functionality of the textbox is normal. Tabbing and taborder works as expected. When I left-click on the textbox with the mouse the cursor appears. I’ve trapped the event arguments in the debugger and have constructed an identical mouse event.
Btw, the OnMouseClick method only appears to be available on the textbox’s mouseclick event.
Any ideas

Cursor in a textbox window
enrialva
Control added is called when the control is added, not when the index is changed. You need to handle the SelectedIndexChanged event of the tab control if you want your code to be called when the page becomes visible.
rimz
This will only work on the last tab control in the list. Why not just grab the SelectedTabPage property of the tab control
Yes, a fully recursive solution would be better, but I have no idea why I got that error when I tried to impliment that. Another solution is to create classes derived from TabPage, and add a method that sets the focus to a control that you set, in other words, add a control property and a method that calls focus on it. Then when the index changes, if the selectedtabpage is of that type, cast it and call the method.
Quicker
ausmock
Oh, OK. I'd still figure out the recursive solution if I were you, just in case your form changes, and because it's 'nicer'. :-)
regthesk8r
Here's the whole thing all you need is a large form with a tab control,
and and a go and exit button
Public Class Form1
Protected a As Tabp
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Sub cbGo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbGo.Click
a = New Tabp(TabControl1)
TabControl1.Controls.Add(a.GetTab)
TabControl1.SelectTab(TabControl1.Controls.Count - 1)
End Sub
Public ReadOnly Property GetTabSize() As Size
Get
For i As Short = 0 To Me.Controls.Count - 1
If Me.Controls(i).GetType.ToString = GetType(Windows.Forms.TabControl).ToString Then
Return Me.Controls(i).Size
End If
Next
End Get
End Property
Private Sub cbExit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbexit.Click
End
End Sub
Private Sub TabControl1_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles TabControl1.ControlAdded
End Sub
End Class
Public Class Tabp
Inherits Windows.Forms.Form
Protected Friend WithEvents t As New TabPage
Protected Friend WithEvents rtf As New RichTextBox
Protected Friend WithEvents tb As New TextBox
Protected Friend WithEvents cbOK As New Button
Protected Friend WithEvents cbCancel As New Button
Protected Friend WithEvents ctxmnu As New ContextMenu
Protected gbControls As New GroupBox
Protected gbRtf As New GroupBox
Protected Parent1 As TabControl
Public Sub New(ByVal ParentControl As TabControl)
Parent1 = ParentControl
gbRtf.Size = Form1.GetTabSize
gbRtf.Height -= 100
gbRtf.Width -= 20
ctxmnu.MenuItems.Add("test")
t.Text = "Blank Document"
gbRtf.Location = New Point(10, 10)
rtf.ScrollBars = RichTextBoxScrollBars.Both
rtf.Size = New Size(gbRtf.Width - 10, gbRtf.Height - 20)
rtf.BorderStyle = BorderStyle.None
rtf.Location = New Point(5, 10)
rtf.ContextMenu = ctxmnu
gbControls.Controls.Add(tb)
t.Controls.Add(gbControls)
gbControls.Height = 50
gbControls.Width = gbRtf.Width
gbControls.Left = gbRtf.Left
gbControls.Top = gbRtf.Top + gbRtf.Height + 5
gbControls.Controls.Add(cbOK)
gbControls.Controls.Add(cbCancel)
t.Controls.Add(gbRtf)
gbRtf.Controls.Add(rtf)
tb.Location = New Size(20, 20)
tb.Size = New Point(gbControls.Width - 200, 20)
tb.TabStop = True
tb.Name = "tb"
tb.AcceptsReturn = True
cbOK.Size = New Size(50, 30)
cbCancel.Size = New Size(50, 30)
cbOK.Location = New Point(tb.Left + tb.Width + 120, 15)
cbCancel.Location = New Point(tb.Left + tb.Width + 20, cbOK.Top)
cbCancel.Text = "Cancel"
cbOK.Text = "OK"
End Sub
Public Function GetTab() As TabPage
Return t
End Function
Private Sub Tb_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tb.KeyPress
If e.KeyChar = Chr(Keys.Enter) Then
t.Text = tb.Text.Substring(0, tb.Text.IndexOf(" "))
e.Handled = True
End If
End Sub
Public Sub Dispose1()
t.Dispose()
ctxmnu.Dispose()
ctxmnu = Nothing
rtf.Dispose()
t = Nothing
rtf = Nothing
gbRtf.Dispose()
gbControls.Dispose()
gbControls = Nothing
cbOK.Dispose()
cbOK = Nothing
cbCancel.Dispose()
cbCancel = Nothing
tb.Dispose()
tb = Nothing
End Sub
Private Sub cbCancel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbCancel.Click
t.Hide()
Parent1.Controls.Remove(t)
Parent1.SelectTab(0)
Me.Dispose1()
Me.Dispose()
End Sub
Private Sub t_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles t.ControlAdded
gbControls.TabIndex = 0 ' container for the textbox
tb.TabIndex = 0 ' taborder is 0
'Dim a As New MouseEventArgs(Windows.Forms.MouseButtons.Left, 1, 8, 8, 0)
'tb_MouseClick(tb, a)
tb.Focus()
End Sub
Private Sub tb_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tb.MouseClick
'Me.OnMouseClick(e)
End Sub
Private Sub rtf_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles rtf.MouseDown
If Not SystemInformation.MouseButtonsSwapped() Then
If e.Button = Windows.Forms.MouseButtons.Right Then
ctxmnu.Show(rtf, e.Location)
End If
Else
If e.Button = Windows.Forms.MouseButtons.Left Then
ctxmnu.Show(rtf, e.Location)
End If
End If
End Sub
End Class
lx
david123098
Because you're creating this page dynamically, you need some other method of finding the text box. I tried to add a recursive method and call it from selectedindex changed:
Private Sub SetFocus(ByVal ctrl As ControlCollection)
Dim c As Control
For Each c In ctrl
If TypeOf (c) Is TextBox Or TypeOf (c) Is RichTextBox Then
c.Focus()
End IfSetFocus(c.Controls)
Next End SubBut I got errors converting from TabPageControlCollection to ControlCollection. I tried iterating through the top level first and calling this, I got an error converting ControlCollection to ControlCollection. In each case, the actual error was something like 'number must be less than infinity'. I don't know why, but as only one level of recursion was required, the following code works.
Private Sub OnselectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged Dim c As Control For Each c In TabControl1.SelectedTab.Controls If TypeOf (c) Is TextBox Or TypeOf (c) Is RichTextBox Thenc.Focus()
End If Dim ctrl As Control For Each ctrl In c.Controls If TypeOf (ctrl) Is TextBox Or TypeOf (ctrl) Is RichTextBox Thenctrl.Focus()
End If Next Next End SubNaturally, the bug I had needs fixing so you can use recursion instead of doing it like this, but the basic approach of finding the control and calling Focus() works just fine. The other approach is to maintain a hashtable of tab pages to controls to focus, and look that up to call Focus when the tab page changes.
jm47048
Cgraus, thank you for your reply.
That recommendation came from the VS2005 help file, actually I think it's really cool only it doesn't work.
I've experimented with setting the focus and it hasn't worked.
How would you set the focus, cgraus
David Blaettler
Ok thank you.... I got it... but it was NASTY!
I gues it must be a question of sequencing and I've seen this before and had similar problems. Anyway here the solution and it's not pretty because it knows too much about the class etc. There really should be a better way to do this.
Private Sub TabControl1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TabControl1.SelectedIndexChanged
Dim lasttab As Control = TabControl1.Controls(TabControl1.Controls.Count - 1)
Dim c As Control
For i As Short = 0 To lasttab.Controls.Count - 1
If TypeOf lasttab.Controls(i) Is GroupBox Then
c = lasttab.Controls(i)
For ii As Short = 0 To c.Controls.Count - 1
If TypeOf c.Controls(ii) Is TextBox Then
c.Controls(ii).Focus()
Exit Sub
End If
Next
End If
Next
End Sub
End Class
Thank you!!!!!!
dakhili
cgraus... thank you but I still have a problem....
Here is what I did....
Private Sub t_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles t.ControlAdded
gbControls.TabIndex = 0 ' container for the textbox
tb.TabIndex = 0 ' taborder is 0
For i As Short = 0 To t.Controls.Count - 1
If t.Controls(i).Name = "gbcontrols" Then
Dim gb As GroupBox = t.Controls(i)
For ii As Short = 0 To gb.Controls.Count - 1
If TypeOf gb.Controls(ii) Is TextBox Then
gb.Controls(ii).Focus()
Exit Sub
End If
Next
End If
Next
End Sub
It finds the control and executes the .focus... but... there is no cursor in the textbox.
martin911
Can't you set the Focus of the textbox when the tab page becomes visible Similating a mouse click seems a bit hacky to me.
Josh Smith
I created a tab control and put two tabs on it, a richtextbox on one and a text box on the other. Then I did this:
If TabControl1.SelectedIndex = 0 ThenTextBox1.Focus()
ElseRichTextBox1.Focus()
End Ifseems to work fine :-)
tdumitr
I made it work on the last control on the list on purpose.
You see, I want it only when I've just added the control so I did that on purpose.
This text box is for titles, it's the first thing one does is to fill in the title. If another page is selected, I won't even want to the cursor to be in the text box when it returns because the information will already be in the textbox.
Aero.NET
I tried that.
Want to see the code