I'm making a custom login form for a program that is invoked similar to a messagebox, returning a DialogResult to show whether the login was successful. There are three buttons, each returning a different DialogResult. (The code for actually checking the login data is not implemented yet.) However, only the Cancel button actually fires the appropriate Event, the other buttons do nothing.
Public Class LoginBox
Inherits Form
Private WithEvents btnLogin As New Button With {.Text = "Login", .Size = New Size(80, 25), .Location = New Point(230, 90), .BackColor = Color.Silver}
Private WithEvents btnCancel As New Button With {.Text = "Cancel", .Size = New Size(80, 25), .Location = New Point(230, 120), .BackColor = Color.Silver}
Private WithEvents btnReadOnly As New Button With {.Text = "Open in" & vbCrLf & "readonly" & vbCrLf & "mode", .Size = New Size(80, 55), .Location = New Point(130, 90), .BackColor = Color.Silver}
Private WithEvents tbNaam As New TextBox With {.Size = New Size(180, 20), .BackColor = Color.Silver, .Location = New Point(130, 20)}
Private WithEvents tbWachtwoord As New TextBox With {.Size = New Size(180, 20), .BackColor = Color.Silver, .Location = New Point(130, 55)}
Private lblNaam As New Label With {.Text = "Inlognaam:", .ForeColor = Color.Silver, .Location = New Point(65, 23)}
Private lblWachtwoord As New Label With {.Text = "Wachtwoord:", .ForeColor = Color.Silver, .Location = New Point(53, 58)}
Private Shared WaitForButton As New System.Threading.EventWaitHandle(False, Threading.EventResetMode.ManualReset)
Private Shared antwoord As DialogResult
Private Sub New()
Me.FormBorderStyle = FormBorderStyle.FixedDialog
ControlBox = False
Text = "Inlog IC agenda"
AcceptButton = btnLogin
CancelButton = btnCancel
Size = New Size(350, 205)
BackColor = Color.DimGray
Controls.Add(btnLogin)
Controls.Add(btnCancel)
Controls.Add(btnReadOnly)
Controls.Add(tbNaam)
Controls.Add(tbWachtwoord)
Controls.Add(lblNaam)
Controls.Add(lblWachtwoord)
End Sub
Public Overloads Shared Function Show(ByVal ShowReadOnlyButton As Boolean) As DialogResult
Dim X As New LoginBox
If Not ShowReadOnlyButton Then
X.btnReadOnly.Visible = False
X.Size = New Size(350, 180)
X.btnCancel.Location = New Point(130, 90)
End If
X.CenterToParent()
X.ShowDialog()
WaitForButton.WaitOne()
Return antwoord
End Function
Private Sub btnLogin_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLogin.Click
'TODO: check login data, if incorrect, show error message
antwoord = DialogResult.OK
WaitForButton.Set()
End Sub
Private Sub btnCancel_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCancel.Click
antwoord = DialogResult.Cancel
WaitForButton.Set()
End Sub
Private Sub btnReadOnly_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnReadOnly.Click
antwoord = DialogResult.Ignore
WaitForButton.Set()
End Sub
End Class
Testing shows the Cancel button working as expected. The other two buttons fail to raise the appropriate event, even though (in my eyes) they are coded in exactly the same way.
Button handlers are working, but the form is not closed. The reason is that you miss a line in event handlers.
DialogResult = antwoord
So, your event handlers should look similar like shown in the code below.
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
'TODO: check login data, if incorrect, show error message
antwoord = DialogResult.OK
DialogResult = antwoord
WaitForButton.Set()
End Sub
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
antwoord = DialogResult.Cancel
DialogResult = antwoord
WaitForButton.Set()
End Sub
Private Sub btnReadOnly_Click(sender As Object, e As EventArgs) Handles btnReadOnly.Click
antwoord = DialogResult.Ignore
DialogResult = antwoord
WaitForButton.Set()
End Sub
"Cancel" is treated like DialogResult.None, so you had an impression that "Cancel" only works correctly.
Related
Visual Studio 2019, Visual Basic.
I have a Form. On load i add a lot of textbox. I need to hide layout during this process. I try:
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SuspendLayout()
MakePanel() ' Sub adding textbox
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
But it showing all process. I Try
Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Panel1.visible = false
MakePanel() ' Sub adding textbox
Me.Panel1.visible = true
End Sub
But nothing ...
I don't have the rep to comment but your second attempt is on the right track. The problem likely lies in your MakePanel() function not actually adding all the text boxes within Panel1's control but rather as part of your form itself. So when you go to hide the panel, it doesn't hide the text boxes within it.
They need to be added via Panel1.Controls.Add to actually 'hide' with Panel1
ie (starting with a new blank form):
Public Panel1 = New Panel()
Public TextBox1 = New TextBox()
Public TextBox2 = New TextBox()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Controls.Add(Panel1)
Panel1.Visible = False
MakePanel()
Panel1.Visible = True
End Sub
Private Sub MakePanel()
Panel1.Location = New Point(3, 3)
Panel1.Name = "Panel1"
Panel1.Size = New Size(100, 100)
Panel1.TabIndex = 0
TextBox1.Location = New Point(3, 3)
TextBox1.Name = "TextBox1"
TextBox1.Size = New Size(49, 20)
TextBox1.TabIndex = 0
Panel1.Controls.Add(TextBox1)
TextBox2.Location = New Point(3, 29)
TextBox2.Name = "TextBox2"
TextBox2.Size = New Size(49, 20)
TextBox2.TabIndex = 1
Panel1.Controls.Add(TextBox2)
End Sub
Hope this helps!
With the help of the code below (by LarsTech - drag and detach tabpages
) I was able to detach a tabpage and place it into a new form. But when I close that form the dragged tabpage doesn't return to its original position.
If anyone out there can help me program this, it'll be great!
Private Sub TabControl1_MouseMove(sender As Object, e As MouseEventArgs) Handles TabControl1.MouseMove
If (e.Button = MouseButtons.Left) Then
TabControl1.DoDragDrop(TabControl1.SelectedTab, DragDropEffects.Move)
End If
End Sub
Private Sub TabControl1_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles TabControl1.GiveFeedback
e.UseDefaultCursors = False
End Sub
Private Sub TabControl1_QueryContinueDrag(sender As Object, e As QueryContinueDragEventArgs) Handles TabControl1.QueryContinueDrag
If Control.MouseButtons <> MouseButtons.Left Then
e.Action = DragAction.Cancel
Dim f As New Form
f.Size = New Size(400, 300)
f.StartPosition = FormStartPosition.Manual
f.Location = MousePosition
Dim tc As New TabControl
tc.Dock = DockStyle.Fill
tc.TabPages.Add(TabControl1.SelectedTab)
f.Controls.Add(tc)
f.Show()
Me.Cursor = Cursors.Default
Else
e.Action = DragAction.Continue
Me.Cursor = Cursors.Help
End If
End Sub
I've been able to produce the code which returns the tabpage to its original place when the form closes, however the page doesn't return to the original index position. Below is the updated code:
Public f As Form
Private Sub TabControl1_MouseMove(sender As Object, e As MouseEventArgs) Handles TabControl1.MouseMove
If (e.Button = MouseButtons.Left) Then
TabControl1.DoDragDrop(TabControl1.SelectedTab, DragDropEffects.Move)
End If
End Sub
Private Sub TabControl1_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles TabControl1.GiveFeedback
e.UseDefaultCursors = False
End Sub
Private Sub TabControl1_QueryContinueDrag(sender As Object, e As QueryContinueDragEventArgs) Handles TabControl1.QueryContinueDrag
f = New Form
If Control.MouseButtons <> MouseButtons.Left Then
e.Action = DragAction.Cancel
AddHandler f.FormClosing, AddressOf ClosingDraggableWindow_EventHandler
f.Size = New Size(400, 300)
f.Name = TabControl1.SelectedTab.Text
f.TabIndex = TabControl1.SelectedTab.TabIndex
f.StartPosition = FormStartPosition.Manual
f.Location = MousePosition
Dim tc As New TabControl()
tc.Dock = DockStyle.Fill
tc.TabPages.Add(TabControl1.SelectedTab)
f.Controls.Add(tc)
f.Show()
End If
End Sub
Sub ClosingDraggableWindow_EventHandler()
Dim tbp As New TabPage()
tbp.Text = f.Name
Dim tbc As TabControl = f.Controls(0)
Dim tbp2 As TabPage = tbc.TabPages(0)
TabControl1.TabPages.Insert(f.TabIndex + 1, tbp2)
End Sub
Changing this sentence
f.TabIndex = TabControl1.SelectedTab.TabIndex
to
f.TabIndex = TabControl1.SelectedIndex
it works fine.
TabIndex represents the order into the form but not the index into the TabControl1.
I probably encountered an issue of Visual Studio 2015. If you define three handlers of the same event using WithEvents and Handles keywords, one of the handlers will not be called. I traced this behavior in our software and wrote following WinForms sample project.
Public Class MainBase1
Inherits Form
Protected WithEvents Button1 As Button
Protected TextBox1 As TextBox
Public Sub New()
SuspendLayout()
Text = "WithEvents Test"
ClientSize = New Size(300, 300)
Button1 = New Button()
Button1.Location = New Point(10, 10)
Button1.Size = New Size(100, 25)
Button1.Text = "Button1"
Controls.Add(Button1)
TextBox1 = New TextBox()
TextBox1.Location = New Point(10, 50)
TextBox1.Multiline = True
TextBox1.Size = New Size(280, 240)
Controls.Add(TextBox1)
ResumeLayout(False)
PerformLayout()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "MainBase1: Button click handled." & vbNewLine
End Sub
End Class
Public Class MainBase2
Inherits MainBase1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "MainBase2: Button click handled." & vbNewLine
End Sub
End Class
Public Class Main
Inherits MainBase2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text &= "Main: Button click handled." & vbNewLine
End Sub
End Class
After clicking Button1 Textbox1 contains
MainBase1: Button click handled.
Main: Button click handled.
If I compile the same sample under Visual Studio 2012, I get
MainBase1: Button click handled.
MainBase2: Button click handled.
Main: Button click handled.
Has anybody encountered this issue as well? Or have I missed something?
This bug still remains. Here is my solution to this.
I made the handler in MainBase1 Protected Overridable. Subclasses don't use Handles but override the handler and call MyBase.
This approach has the advantage that execution order of handlers is well-defined.
Public Class MainBase1
Inherits Form
Protected WithEvents Button1 As Button
Protected TextBox1 As TextBox
Public Sub New()
SuspendLayout()
Text = "WithEvents Test"
ClientSize = New Size(300, 300)
Button1 = New Button()
Button1.Location = New Point(10, 10)
Button1.Size = New Size(100, 25)
Button1.Text = "Button1"
Controls.Add(Button1)
TextBox1 = New TextBox()
TextBox1.Location = New Point(10, 50)
TextBox1.Multiline = True
TextBox1.Size = New Size(280, 240)
Controls.Add(TextBox1)
ResumeLayout(False)
PerformLayout()
End Sub
Protected Overridable Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click
TextBox1.Text &= "MainBase1: Button click handled." & vbNewLine
End Sub
End Class
Public Class MainBase2
Inherits MainBase1
Protected Overrides Sub Button1_Click(sender As Object, e As EventArgs)
MyBase.Button1_Click(sender, e)
TextBox1.Text &= "MainBase2: Button click handled." & vbNewLine
End Sub
End Class
Public Class Main
Inherits MainBase2
Protected Overrides Sub Button1_Click(sender As Object, e As EventArgs)
MyBase.Button1_Click(sender, e)
TextBox1.Text &= "Main: Button click handled." & vbNewLine
End Sub
End Class
At the moment, I have a button that sends a value to another form and displays result in a label. The problem is, I have 20 buttons that are labeled a to w that need to be coded and I am stumped as to how I can pass values from multiple buttons. Would it be a case statement in the form being passed to? I am a new user to VB.Net and still finding my way so any help would be gratefully received. I have included code sample for the first button 'A'. Thanks
frmMain
Private Sub btnA_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnA.MouseDown
If (e.Button = MouseButtons.Right) Then
'Dim curButton As Button = DirectCast(sender, Button)
'frmRacks.buttonName = curButton.Name 'Dynamic alternative to frmRacks.buttonName = "A"
frmRacks.buttonName = "A"
frmRacks.Show()
ElseIf (e.Button = MouseButtons.Left) Then
MessageBox.Show("To be coded")
End If
End Sub
frmRacks
Public Class frmRacks
Public buttonName As String
Private Sub racksfrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblRacks.Text = buttonName
End Sub
EDIT: New project
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim button1 As Button = New Button
Dim button2 As Button = New Button
Dim button3 As Button = New Button
With button1
.Name = "button1"
.Left = 0
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button1
End With
With button2
.Name = "button2"
.Left = 100
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button2
End With
With button3
.Name = "button3"
.Left = 200
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button3
End With
Me.Controls.Add(button1)
Me.Controls.Add(button2)
Me.Controls.Add(button3)
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim curButton As Button = DirectCast(sender, Button)
Dim curButtonName As String = curButton.Name 'This string would change on account of the button you have clicked
Form2.buttonName = curButtonName
Form2.Show()
'MessageBox.Show("You clicked the button called " & curButtonName.ToUpper)
End Sub
End Class
Public Class Form2
Public buttonName As String
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblRacks.Text = buttonName
End Sub
End Class
Here you have a sample code which hopefully will help you to get clearer ideas:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim button1 As Button = New Button
Dim button2 As Button = New Button
Dim button3 As Button = New Button
With button1
.Name = "button1"
.Left = 0
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button1
End With
With button2
.Name = "button2"
.Left = 100
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button2
End With
With button3
.Name = "button3"
.Left = 200
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button3
End With
Me.Controls.Add(button1)
Me.Controls.Add(button2)
Me.Controls.Add(button3)
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim curButton As Button = DirectCast(sender, Button)
Dim curButtonName As String = curButton.Name 'This string would change on account of the button you have clicked
MessageBox.Show("You clicked the button called " & curButtonName.ToUpper)
End Sub
I'm newbie in vb.net and I just have something to ask you.
I want to create a simple program and I'm trying to do this with run-time design.
with this form, when you click on the button1 with the caption(Text) "Show Another Form", another form will be created with this code:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim NewForm As New Form
Dim btnCancel As New Button
NewForm.StartPosition = FormStartPosition.CenterScreen
NewForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
NewForm.BackColor = Color.WhiteSmoke
NewForm.Size = New Size(400, 200)
NewForm.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable
btnCancel.Text = "Cancel"
btnCancel.Size = New Size(150, 50)
btnCancel.Location = New Point(50, 50)
NewForm.Controls.Add(btnCancel)
NewForm.ShowDialog()
AddHandler btnCancel.Click, AddressOf CancelClick
End Sub
Public Sub cancelclick(ByVal sender As Object, ByVal e As EventArgs)
Dim x As String = MessageBox.Show("Exit", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If x = vbYes Then End
End Sub
End Class
How can I exit the form I've created when you click on the Cancel Button. The code I've provided doesn't work. Pls help me out. Thanks
Try attach handler code before show dialog
NewForm.Controls.Add(btnCancel)
AddHandler btnCancel.Click, AddressOf CancelClick
NewForm.ShowDialog()
In your code change the AddressOf CancelClick to AddressOf cancelclick
EDIT:
Change the NewForm.ShowDialog() to NewForm.Show() and also change the code as below code then definitely it will work.
Public NewForm As Form
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
NewForm = New Form
Dim btnCancel As New Button
NewForm.StartPosition = FormStartPosition.CenterScreen
NewForm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
NewForm.BackColor = Color.WhiteSmoke
NewForm.Size = New Size(400, 200)
NewForm.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable
btnCancel.Text = "Cancel"
btnCancel.Size = New Size(150, 50)
btnCancel.Location = New Point(50, 50)
NewForm.Controls.Add(btnCancel)
AddHandler btnCancel.Click, AddressOf cancelclick
NewForm.Show()
End Sub
Public Sub cancelclick(ByVal sender As Object, ByVal e As System.EventArgs)
Dim x As String = MessageBox.Show("Exit", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
If x = vbYes Then End
End Sub