Menu Item Custom Control Events - vb.net

I am trying to create a menu list item that contains both a textbox and a label as a single item. In the code below I have made the necessary custom control class inherited from ToolStripControlHost and this looks and behaves as expected when created in the form menu.
The problem I am having is that the control's events are not firing the handler routine. In the example below, what I would expect to happen is that when the user types into the text box a message should show (other events have the same problem).
Thank you.
Control Classes:
Public Class ToolStripTextBoxWithLabel
Inherits ToolStripControlHost
Public Sub New(Optional ByVal lblText As String = "label")
MyBase.New(New ControlPanel(lblText))
End Sub
Public ReadOnly Property ControlPanelControl() As ControlPanel
Get
Return CType(Me.Control, ControlPanel)
End Get
End Property
End Class
Public Class ControlPanel
Inherits Panel
Friend WithEvents txt As New TextBox
Friend WithEvents lbl As New Label
Public Sub New(ByVal lblText As String)
Me.Height = 20
lbl.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Bottom
lbl.Text = lblText
lbl.TextAlign = ContentAlignment.BottomLeft
lbl.AutoSize = True
lbl.Height = Me.Height
lbl.Location = New Point(0, 3)
lbl.Parent = Me
txt.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
txt.Location = New Point(lbl.Right + 3, 0)
txt.Width = Me.Width - txt.Left
txt.Parent = Me
End Sub
End Class
Form Implementation:
Public Class Form1
Friend tb_SearchBox As ToolStripTextBoxWithLabel
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
tb_SearchBox = New ToolStripTextBoxWithLabel("Search:") With {.Name = "tb_SearchBox"}
AddHandler tb_SearchBox.TextChanged, AddressOf tb_SearchBox_TextChanged
Item1ToolStripMenuItem.DropDownItems.Add(tb_SearchBox)
End Sub
Private Sub tb_SearchBox_TextChanged(sender As Object, e As EventArgs)
MsgBox("Success")
End Sub
End Class

Using the TextChanged event of your ToolStripTextBoxWithLabel in this instance is inappropriate because that event should only be raised when the Text property of that object changes, which is not happening here. You need to do what Plutonix suggested but you should also do it with your own custom event rather than with the TextChanged event of the host, e.g.
Public Event TextBoxTextChanged As EventHandler
Protected Overridable Sub OnTextBoxTextChanged(e As EventArgs)
RaiseEvent TextBoxTextChanged(Me, e)
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
OnTextBoxTextChanged(EventArgs.Empty)
End Sub
Rather than deriving your ControlPanel class from Panel and creating the child controls in code, I would suggest that you create a user control and add the children in the designer. You would then use my answer below in two steps, i.e. the user control would handle the TextChanged event of the TextBox and then raise an event of its own that would, in turn, be handled by the ToolStripTextBoxWithLabel that would its own event.

Thanks to jmcilhinney and Plutonix I have put together the solution. For completeness and future community reference the full solution is below.
User Control:
Public Class CustomTextBox
Public Event TextBoxTextChanged As EventHandler
Protected Overridable Sub OnTextBoxTextChanged(e As EventArgs)
RaiseEvent TextBoxTextChanged(Me, e)
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
OnTextBoxTextChanged(EventArgs.Empty)
End Sub
Public Sub New (lblText as string)
InitializeComponent()
Caption = lblText
End Sub
Public Property Caption() As String
Get
Return Label1.Text
End Get
Set(ByVal value As String)
Label1.Text = value
End Set
End Property
Public Overrides Property Text() As String
Get
Return TextBox1.Text
End Get
Set(ByVal value As String)
TextBox1.Text = value
End Set
End Property
Public Class
Implementation:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim SearchBox As New CustomTextBox("Search")
Dim host As ToolStripControlHost = new ToolStripControlHost(windowNewMenu)
AddHandler SearchBox.TextBoxTextChanged, AddressOf SearchBox_TextChanged
ToolStripMenuItem1.DropDownItems.Add(host)
End Sub
Private Sub SearchBox_TextChanged(sender As Object, e As EventArgs)
MsgBox(sender.Text)
End Sub

Related

Add event to FileSystemWatcher when property EnableRaisingEvents changed

I have created a custom class
Public Class MyFSW
Inherits FileSystemWatcher
Public Property ParentForm As Form
Public Property TabPage As TabPage
End Class
Now I want to add a custom event to the this class, that fires when the property "EnableRaisingEvents" of the FileSystemWatcher changes?
Is there any chance to do this?
The EnableRaisingEvents property is not declared Overridable so you can't override it. You can shadow it though:
Public Class FileSystemWatcherEx
Inherits FileSystemWatcher
Public Property ParentForm As Form
Public Property TabPage As TabPage
Public Shadows Property EnableRaisingEvents As Boolean
Get
Return MyBase.EnableRaisingEvents
End Get
Set(value As Boolean)
If MyBase.EnableRaisingEvents <> value Then
MyBase.EnableRaisingEvents = value
OnEnableRaisingEventsChanged(EventArgs.Empty)
End If
End Set
End Property
Public Event EnableRaisingEventsChanged As EventHandler
Protected Overridable Sub OnEnableRaisingEventsChanged(e As EventArgs)
RaiseEvent EnableRaisingEventsChanged(Me, e)
End Sub
End Class
That will work as long as you set the property through a reference of type FileSystemWatcherEx. Because the property is shadowed rather than overridden, setting it through a reference of type FileSystemWatcher will bypass the derived property implementation and the event will not be raised. You really can't do anything about that.
Thank you so far!
This is what I got now (in my class-file):
Public Class MyFSW
Inherits FileSystemWatcher
Public Property ParentForm As Form
Public Property TabPage As TabPage
Public Shadows Property EnableRaisingEvents As Boolean
Get
Return MyBase.EnableRaisingEvents
End Get
Set(value As Boolean)
If MyBase.EnableRaisingEvents <> value Then
MyBase.EnableRaisingEvents = value
OnEnableRaisingEventsChanged(EventArgs.Empty)
End If
End Set
End Property
Public Event EnableRaisingEventsChanged As EventHandler
Protected Overridable Sub OnEnableRaisingEventsChanged(e As EventArgs)
RaiseEvent EnableRaisingEventsChanged(Me, e)
End Sub
End Class
In my Form-Class is got this:
Sub CreateFSW()
w.Watcher = New MyFSW With {
.ParentForm = f,
.TabPage = tp,
.Path = w.Path,
.Filter = w.Filter,
.IncludeSubdirectories = w.IncludeSubdirs,
.NotifyFilter = DirectCast(w.NotifyFilter, NotifyFilters)
}
AddHandler w.Watcher.Created, AddressOf Fsw_EventRaise
AddHandler w.Watcher.Changed, AddressOf Fsw_EventRaise
AddHandler w.Watcher.Renamed, AddressOf Fsw_EventRaise
AddHandler w.Watcher.Deleted, AddressOf Fsw_EventRaise
AddHandler w.Watcher.EnableRaisingEventsChanged, AddressOf Fsw_Event
End Sub
Private Sub Fsw_Event(sender As Object, e As FileSystemEventArgs)
MessageBox.Show("Works")
End Sub
The compiler says:
Option Strict On does not allow narrowing in implicit type conversions between method Fsw_Event(sender As Object, e As FileSystemEventArgs) and delegate Delegate Sub EventHandler(sender As Object, e As EventArgs)
Seems that some types does not match. I tried to change FileSystemEventArgs to EventArgs and stuff like this, but without luck.
As a continuation of a “previous example” you can achieve that with some small changes like the example below shows:
In this example the property is changed by clicking a button, but you can implement handlers on your own needs.
Option Strict On
Imports System.IO
Public Class Form1
Private Fsw As CustomFSW
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CreateFSW()
End Sub
Sub CreateFSW()
Fsw = New CustomFSW With {
.Name = "Tab1", 'Adding this you can specify the object is sending the event
.Path = "C:\Users\UserName\Desktop\Test\",
.Filter = "*.*",
.IncludeSubdirectories = True,
.EnableRaisingEvents = True
}
AddHandler Fsw.Created, AddressOf Fsw_Event
AddHandler Fsw.Changed, AddressOf Fsw_Event
AddHandler Fsw.Renamed, AddressOf Fsw_Event
AddHandler Fsw.Deleted, AddressOf Fsw_Event
'Here the handler of your custom event
AddHandler Fsw.MyCutomEvent, AddressOf Fsw_CutomEvent
End Sub
Private Class CustomFSW
Inherits FileSystemWatcher
Private counter As Integer = 0
Public Property Name As String
'You can use the base property instead of this for specific needs
Private _EnableRaisingEvents As Boolean
Public Overloads Property EnableRaisingEvents As Boolean
Get
Return _EnableRaisingEvents
End Get
Set(value As Boolean)
If Not value = _EnableRaisingEvents Then
counter += 1
RaiseEvent MyCutomEvent(Me, "Ciaooo, EnableRaisingEvents is changed " & counter.ToString & " times")
End If
_EnableRaisingEvents = value
End Set
End Property
'Rename this on your needs
Public Event MyCustomEvent(sender As Object, e As String)
End Class
Private Sub Fsw_CustomEvent(sender As Object, e As String)
' Do your stuff here
MsgBox(e)
End Sub
Private Sub Fsw_Event(sender As Object, e As FileSystemEventArgs)
Dim FSW As CustomFSW = CType(sender, CustomFSW)
If Not String.IsNullOrEmpty(FSW.Name) Then
Select Case FSW.Name
Case "Tab1"
'Do something
Debug.WriteLine("Event generated from: " & FSW.Name)
Case "Tab2"
'Do something else
Debug.WriteLine("Event generated from: " & FSW.Name)
End Select
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Fsw IsNot Nothing Then
Fsw.EnableRaisingEvents = Not Fsw.EnableRaisingEvents
End If
End Sub
End Class

How to Trigger button click from another form VB Net

I have three forms in total and i want to trigger one of the button on form 3 to be triggered automatically when form 1 loaded
Form 1
Public Class frmIOMain
' In This Form load I want to trigger the above mentioned button
Private Sub IOMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
' I want to Trigger the Above mentioned button here when my form is loaded
' But it is not working for me
frmUpdateDueDates.cmdUpdate_Click(Nothing, Nothing)
End Sub
End Class
Form 2
Public Class TestEquipmentManagement
Public EquipementTable As New DataTable("EquipmentTable")
Public EquiTypeSelection As String
Public EquiManufacturerSelection As String
Public EquiList_PK As New List(Of Integer)
Dim targetEquipmentList As New List(Of Model.equipment)
Private equipDB As Model.Entities = Nothing
Public Shared viewManager As ViewManager
Private equipment As New List(Of Model.equipment)
'Dim WithEvents excNewPFM As New VBACom
Public EquipCalTable As New DataTable("EquipCalTable")
Public Sub New()
Dim todayplusoneyear As Date
todayplusoneyear = Date.Today
todayplusoneyear = todayplusoneyear.AddYears(1)
'Assign current db
equipDB = frmIOMain.db
End Sub
End Class
Form 3
Public Class frmUpdateDueDates
Private EquipmentUpdates As UpdateCalibrationsViewModel
Private _success As Boolean = False
Public Sub New(db As Entities)
' Dieser Aufruf ist für den Designer erforderlich.
InitializeComponent()
EquipmentUpdates = New UpdateCalibrationsViewModel(db, New CAQ23(), False)
'Add Handlers
AddHandler EquipmentUpdates.OnProgressChanged, AddressOf progressChangedHandler
AddHandler EquipmentUpdates.OnInfotextChanged, AddressOf infoTextChangedHandler
prgUpdates.Maximum = EquipmentUpdates.intProgressMax
End Sub
Public Sub cmdUpdate_Click(sender As Object, e As EventArgs) Handles cmdUpdate.Click
cmdUpdate.Enabled = False
_success = EquipmentUpdates.startUpdating()
cmdCancel.Text = "Close"
End Sub
End Class
I want "cmdUpdate_Click" Button which is on form 3 to be triggered when my form 1 is loaded
Can Anyone tell me how i can do that?
Firstly, create an instance of the form, instead of using its default form instance. Calling a click handler across forms isn't a good idea. The handler may use the arguments sender As Object, e As EventArgs and from outside of the containing class, you can't assume you know that. Better practice would be to create a method which performs the click within the form, such as
Public Class frmUpdateDueDates
Public Sub cmdUpdateClick()
cmdUpdate.PerformClick()
End Sub
Private Sub cmdUpdate_Click(sender As Object, e As EventArgs) Handles cmdUpdate.Click
cmdUpdate.Enabled = False
_success = EquipmentUpdates.startUpdating()
cmdCancel.Text = "Close"
End Sub
End Class
Public Class frmIOMain
Private myFrmUpdateDueDates As frmUpdateDueDates
Private Sub IOMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
myFrmUpdateDueDates = New FrmUpdateDueDates()
myFrmUpdateDueDates.Show()
'myFrmUpdateDueDates.cmdUpdate_Click(Nothing, Nothing)
myFrmUpdateDueDates.cmdUpdateClick()
End Sub
End Class
And you can change the access modifier of the click handler back to Private
Even better would be to put the work into a different method which the click handler calls. Then the other form doesn't even need to know the button exists. Such as
Public Class frmUpdateDueDates
Public Sub DoUpdating()
cmdUpdate.Enabled = False
_success = EquipmentUpdates.startUpdating()
cmdCancel.Text = "Close"
End Sub
Private Sub cmdUpdate_Click(sender As Object, e As EventArgs) Handles cmdUpdate.Click
DoUpdating()
End Sub
End Class
Public Class frmIOMain
Private myFrmUpdateDueDates As frmUpdateDueDates
Private Sub IOMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load
myFrmUpdateDueDates = New FrmUpdateDueDates()
myFrmUpdateDueDates.Show()
'myFrmUpdateDueDates.cmdUpdate_Click(Nothing, Nothing)
myFrmUpdateDueDates.DoUpdating()
End Sub
End Class

Create an event. This event should occur when a certain string has changed

I go far back to make clear the context. First, I noticed today that if there are several controls on the form, you cannot use the arrow keys because the controls (e.g. ComboBox, textbox) take the cursor and focus. Therefore, I created a second form ("SteuerForm" (Steering Form)). There are no controls on this. I also found out that you can only get the arrow keys with the KeyDown event. The KeyDown event is disadvantageous when it comes to certain characters: "Shiftkey" and "Oem7" are output instead of the specific letter (e.g. Ä). That's why I actually wanted to use KeyPress. Eventually, I wrote a class ("Class_Key"). It contains a list(Of string) with certain key names that I must have.
Now I want the Private Sub new_message() in Form1 to be called when the string letzte_Taste (last_key) changes.
Edit: I want some event in the Class_Key Class to fire a method (new_message) in the main form. How can I do that? The event is supposed to be fired when the string letzte_Taste changes from one (eg "Up") to another (eg "Down").
SteuerForm.vb
Public NotInheritable Class SteuerForm
Private Sub SteuerForm_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
If Class_Key.Tasten.Contains(e.KeyChar.ToString) Then
Class_Key.letzte_Taste = e.KeyChar.ToString
End If
End Sub
Private Sub SteuerForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
Me.Location = New Point(500, 0)
End Sub
Private Sub SteuerForm_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If Class_Key.Tasten.Contains(e.KeyCode.ToString) Then
Class_Key.letzte_Taste = e.KeyCode.ToString
End If
End Sub
End Class
Class_Key.vb
Public NotInheritable Class Class_Key
Public Shared Tasten As New List(Of String) From {
"Up",
"Down",
"Left",
"Right",
"Return",
"Back",
"Space",
"Add",
"Subtract",
"a"} 'and another alphabetic characters... (I shortened this...)
Public Shared letzte_Taste As String = ""
End Class
I did it! This is my solution.
Public NotInheritable Class Class_Key
Public Shared Tasten As New List(Of String) From {
"Up",
"Down",
"Left",
"Right",
"Return",
"Back",
"Space",
"Add",
"Subtract",
"a"}
Public Shared Property letzte_Taste As String = ""
Public Shared Property vorletzte_Taste As String = ""
Public Shared Event AnEvent()
Public Shared Zaehler As UInt16 = 0
Public Shared Sub Pruefung()
If Not letzte_Taste = vorletzte_Taste Then
RaiseEvent AnEvent()
Zaehler += Convert.ToUInt16(1)
End If
End Sub
End Class
Public NotInheritable Class SteuerForm
Private Sub SteuerForm_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
If Class_Key.Tasten.Contains(e.KeyChar.ToString) Then
Class_Key.letzte_Taste = e.KeyChar.ToString
End If
Class_Key.Pruefung()
Class_Key.vorletzte_Taste = Class_Key.letzte_Taste
End Sub
Private Sub SteuerForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
Me.Location = New Point(500, 0)
End Sub
Private Sub SteuerForm_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If Class_Key.Tasten.Contains(e.KeyCode.ToString) Then
Class_Key.letzte_Taste = e.KeyCode.ToString
End If
Class_Key.Pruefung()
Class_Key.vorletzte_Taste = Class_Key.letzte_Taste
End Sub
End Class
in Form1_Load
AddHandler Class_Key.AnEvent, AddressOf neue_Nachricht
in Form1
Private Sub neue_Nachricht()
Debug.WriteLine($"caught event. Nr. {Class_Key.Zaehler}")
End Sub

how to safe call a control from another thread using Timers.Timer

I read various posts, and made a practice project, but it does not works.
The form have a button and a text box with a default text 'Updated 0 times'. On button click starts the timer and each time update the text with the number of times the text was updated.
The exception of cross thread calls is not thrown, but when calling the text box, its .Text = "", the text is updated but not the text box on the form. And InvokeRequired is always false.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Here the textBox.Text = "Updated 0 times."
Dim checking_text As String = Me.TextBox1.Text
TimerTest.StartTimer()
End Sub
Delegate Sub UpdateTextInvoke(ByVal new_text As String)
Public Sub UpdateText(ByVal new_text As String)
'Here the textBox.Text = ""
Dim txtB As TextBox = Me.TextBox1
'InvokeRequired always = False.
If txtB.InvokeRequired Then
Dim invk As New UpdateTextInvoke(AddressOf UpdateText)
txtB.Invoke(invk, New Object() {new_text})
Else
'The value of this text box is updated, but the text on the form TextBox1 never changes
txtB.Text = new_text
End If
End Sub
End Class
Public Class TimerTest
Private Shared tmr As New System.Timers.Timer
Private Shared counter As Integer
Public Shared Sub StartTimer()
tmr.Interval = 5000
AddHandler tmr.Elapsed, AddressOf UdpateText
tmr.Enabled = True
End Sub
Public Shared Sub UdpateText(ByVal sender As Object, ByVal e As System.EventArgs)
counter += 1
Form1.UpdateText(String.Format("Updated {0} time(s).", counter))
End Sub
End Class
SOLVED
In the Class TimerTest added this code 'Private Shared myform As Form1 = Form1'
then changed 'Form1.UpdateText' To 'myform.UpdateText'
As indicated in the comments, you are using the default form instance feature of VB.Net. You could pass an instance of the form to the TimerTest class, and replace the reference to Form1 with the instance.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim checking_text As String = Me.TextBox1.Text
TimerTest.StartTimer(Me)
End Sub
Public Sub UpdateText(new_text As String)
If TextBox1.InvokeRequired Then
Dim invk As New Action(Of String)(AddressOf UpdateText)
TextBox1.Invoke(invk, {new_text})
Else
TextBox1.Text = new_text
End If
End Sub
End Class
Public Class TimerTest
Private Shared tmr As New System.Timers.Timer()
Private Shared counter As Integer
Private Shared instance As Form1
Public Shared Sub StartTimer(formInstance As Form1)
instance = formInstance
tmr.Interval = 5000
AddHandler tmr.Elapsed, AddressOf UdpateText
tmr.Enabled = True
End Sub
Public Shared Sub UdpateText(ByVal sender As Object, ByVal e As System.EventArgs)
counter += 1
instance.UpdateText(String.Format("Updated {0} time(s).", counter))
End Sub
End Class

Making combobox visible when it is disabled

I am disabling combobox in VB.net.
But in disable mode it not visible properly.
I tried changing both BackColor and ForeColor but it is not working.
Code :
cmbbox.BackColor = Color.FromName("Window")
or
cmbbox.ForeColor = Color.FromName("Window")
Please help
Dear Adam:
I am making my component enable false.But I want to make it viewable.You can reffer the link.This is what exacly I want but in VB.Net : A combobox that looks decent when it is disabled
To achieve disabling combobox without fading it, first change the dropdown style of the combobox to DropDownList, Then tweak with the events to achieve the goal.
Here is a piece of code by which you can achieve the same:
Public Class Form1
Dim selectindex As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.Add("1")
ComboBox1.Items.Add("2")
ComboBox1.Items.Add("3")
ComboBox1.Items.Add("4")
selectindex = 3
ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
ComboBox1.SelectedIndex = selectindex
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox1.SelectedIndex = selectindex
End Sub
End Class
Create anew form Form1 and add a combobox to the form, then add the above code to get a readonly combobox.
Have a look at this thread which has a solution for a readonly combobox and the code is all VB.NET.
A version of their code is as follows. You'll need to but it inside a class of your own which inherits System.Windows.Forms.ComboBox
Private _ReadOnly As Boolean = False
Public Property [ReadOnly]() As Boolean
Get
Return _ReadOnly
End Get
Set(ByVal Value As Boolean)
_ReadOnly = Value
End Set
End Property
Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean
'Prevent keyboard entry if control is ReadOnly
If _ReadOnly = True Then
'Check if its a keydown message
If msg.Msg = &H100 Then
'Get the key that was pressed
Dim key As Int32 = msg.WParam.ToInt32
'Ignore navigation keys
If key = Keys.Tab Or key = Keys.Left Or key = Keys.Right Then
'Do nothing
Else
Return True
End If
End If
End If
'Call base method so delegates receive event
Return MyBase.PreProcessMessage(msg)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'Prevent list displaying if ReadOnly
If _ReadOnly = True Then
If m.Msg = &H201 OrElse m.Msg = &H203 Then
Return
End If
End If
'Call base method so delegates receive event
MyBase.WndProc(m)
End Sub
I've been looking for the same not long ago and ended up doing the following. You may not like it, but i'll share it in case. I am using TableLayoutPanel to arrange my controls on the form and then i am swapping the positions of the desired controls.
For example I've created the following Items:
Form1 Design
TableLayoutPanel1 (two columns, three rows)
TextBox1 Read-only = True, BackColor = White
ComboBox1 Visible = False, DropDownStyle = DropDownList, FlatStyle = Popup
Button1 (named it to Change)
Button2 (named it to Done) -> Visible = False
Runtime - Screenshots
Here is my code:
Public Class Form1
Private Sub SwapControls(tlp As TableLayoutPanel, ctr1 As Control, ctr2 As Control)
Dim ctl1pos As TableLayoutPanelCellPosition = tlp.GetPositionFromControl(ctr1)
ctr1.Visible = False
tlp.SetCellPosition(ctr1, tlp.GetPositionFromControl(ctr2))
ctr2.Visible = True
tlp.SetCellPosition(ctr2, ctl1pos)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SwapControls(TableLayoutPanel1, TextBox1, ComboBox1)
SwapControls(TableLayoutPanel1, Button1, Button2)
Label1.Select()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SwapControls(TableLayoutPanel1, ComboBox1, TextBox1)
SwapControls(TableLayoutPanel1, Button2, Button1)
Label1.Select()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Select()
ComboBox1.SelectedIndex = 0
TextBox1.Text = ComboBox1.SelectedItem
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
TextBox1.Text = ComboBox1.SelectedItem
End Sub
End Class