I have several buttons in which all of them have come codes. I want the user to only can make click the buttons once. How can I do it without having a long disable buttons code?
Dim oneClick As Integer
Private Sub btnPro_Click(sender As Object, e As EventArgs) Handles btnPro.Click
oneClick += 1
If oneClick = 1 Then
Dim ucP As New ucPro
fillMenu(ucP)
End If
End Sub
This is the code I come up with.
EDIT : The point is that I want to click a button once, but the others can be clicked. For example, I have a form with 6 buttons, every button has some codes. If I click Button1, it'll do such code only once, therefore if I click it again, it will not do that code, because it already did it. Then, if I click Button2, it'll do the code once. And what about if I click Button1 again? well, it'll be able to do that code because I clicked to another button.
Sorry for the way I explain myself. I hope you get it.
Keep track of last clicked button and you can use one handler for all involved buttons
Private _lastClickedButton As Button = Nothing
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim button = DirectCast(sender, Button)
If button Is _lastClickedButton Then Exit Sub
_lastClickedButton = button
' Now based on button instance you can execute corresponding logic/method
End Sub
Based on your rather poor explanation, it sounds like what you actually mean is that you only want each button to act once in a row, i.e. once you click a button you need to click another button before the first button does anything again. In that case, the proper way to handle this is to not use Button controls.
Instead of using Button controls and handling their Click events, you should be using RadioButton controls and handling their CheckedChanged events. You can set the Appearance property to Button and they will look just like regular Buttons. When checked, they will appear depressed and that will indicate to the user that they can't be used again.
Here's an example of a form using such controls:
And here's what the appropriate code might look like:
Private Sub RadioButton1_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton1.CheckedChanged
If RadioButton1.Checked Then
'Do something.
End If
End Sub
Private Sub RadioButton2_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
If RadioButton1.Checked Then
'Do something else.
End If
End Sub
Private Sub RadioButton3_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton3.CheckedChanged
If RadioButton1.Checked Then
'Do yet something else.
End If
End Sub
Here's what the form might look like when a RadioButton has been checked:
As you can see, it's nice and clear to the user which one they cannot use.
EDIT:
If you are really determined to use Button controls then you absolutely should be disabling them as that is the standard way that feedback has been provided to the user for decades. It's very simple to disable a Button if and only if it is the last one clicked. Here's an example:
Private Sub AllButtons_Click(sender As Object, e As EventArgs) Handles Button3.Click,
Button2.Click,
Button1.Click
For Each btn In Controls.OfType(Of Button)
btn.Enabled = (btn IsNot sender)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Do something.
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'Do something else.
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
'Do yet something else.
End Sub
Note that you can handle multiple events with a single method and multiple methods can handle a single event, both of which are demonstrated here. All four of those methods were generated automatically by the designer, so I just had to add the body code. Note that the first method assumes that all Button controls on the form will be treated this way. If that's not the case then would need a slight adjustment but nothing too major.
Related
My Form include Notify icon with ContexMenu. ContextMenu is automatically closed when click on any item (AutoClose=True). But if I click anywhere else (away from context menu), ContextMenu remains visible. How to hide it in this case?
Found one answer, that hiding context menu when click somewhere else is standard behavior of context menu. In my case it doesnt work :).
I tried to use ContextMenuStrip Leave or LostFocus event to hide but this didnt work.
To show context menu:
Private Sub NotifyIcon1_DoubleClick(sender As Object, e As EventArgs)
Handles NotifyIcon1.DoubleClick
NotifyIcon1.ContextMenuStrip.Show(MousePosition)
End Sub
To hide context menu I tried:
Private Sub ContextMenuStrip_Leave(sender As Object, e As EventArgs)
Handles ContextMenuStrip.Leave
NotifyIcon1.ContextMenuStrip.Hide()
End Sub
Private Sub ContextMenuStrip_LostFocus(sender As Object, e As EventArgs)
Handles ContextMenuStrip.LostFocus
NotifyIcon1.ContextMenuStrip.Hide()
End Sub
UPDATE: This works:
Private Sub ContextMenuStrip_MouseLeave(sender As Object, e As EventArgs)
Handles ContextMenuStrip.MouseLeave
NotifyIcon1.ContextMenuStrip.Hide()
End Sub
Could be used as temp solution, but original question still open.
I am trying to add some items to a combo box in VB, but when I add the items to the click event handler of the combo-box, and run the code, the items added do not show.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Me.Refresh()
ComboBox1.Items.Clear()
ComboBox1.Items.Add("Mondad")
ComboBox1.Items.Add("Tuesday")
ComboBox1.Items.Add("Wenesday")
ComboBox1.SelectedIndex = 1
End Sub
I mean nothing shows inside the combo-box.
I add the items to the click event handler of the combo-box
Pay special attention to the name of the method:
ComboBox1_SelectedIndexChanged()
Note the emphasis. It sure looks like this is NOT the click event. The click event method would look like this:
ComboBox1_Click(object sender, EventArgs e)
Just changing the name of the method will not be enough, because the method still will not be wired up correctly. Create a new empty event handler in Visual Studio for the click event and move the code there.
Just add this to your code i think it will work
Private Sub ComboBox1_Click(sender As Object, e As EventArgs) Handles ComboBox1.Click
ComboBox1.Items.Clear()
ComboBox1.Items.Add("Mondad")
ComboBox1.Items.Add("Tuesday")
ComboBox1.Items.Add("Wenesday")
ComboBox1.SelectedIndex = 1
End Sub
hope it helps
Put in form load
` Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.Items.Clear()
ComboBox1.Items.Add("Mondad")
ComboBox1.Items.Add("Tuesday")
ComboBox1.Items.Add("Wenesday")
End Sub`
Let me explain further. Let's say I have 20 buttons on a form, and in the all of the button's click event I want to call a specific function, instead of placing the calling to that function in each click event, is there a way to call it from any of the click events without having to place the code in each click event?
Hope that makes sense.
Yes, just add the click event for each button to the end of the Handles clause.
Private Sub My_Sub(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
' do stuff
End Sub
If you have a lot of buttons or a dynamic number of buttons, you could use a recursive method to add the same event handler for each. This will take care of all buttons, even those inside group boxes or other containers.
First, create the method you want each button click to call.
Private Sub bt_ButtonClick(ByVal sender As System.Object, ByVal e As System.EventArgs)
'
' Your code goes here
'
End Sub
Second, create a method to recursively find all the button controls and add the event handler.
Private Sub AddEventHandler(RootControl As Control)
For Each c As Control In RootControl
If c.HasChildren Then
AddEventHandler(c)
End If
If TypeOf c Is Button Then
AddHandler c.Click, AddressOf bt_ButtonClick
End If
Next
End Sub
Lastly, in your form load event, add this line:
AddEventHandler(Me)
Wire the one sub to the click event for every button.
Private Sub AnyButton_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
End Sub
I have a VB program that has two forms, i have coded the form load of each forms.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MessageBox.Show("I AM FORM 1")
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MessageBox.Show("I AM FORM 2")
End Sub
Here is how i switch through Form1 and Form2, i made use of a button.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Hide()
Form1.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Hide()
Form2.Show()
End Sub
But everytime i switch forms the form load event will only trigger once. Is there something wrong with my code? I am guesing the Me.Hide() will only hide the previous form and not totally close it. I want to be able to close the previous form so that when i will open it again, the form load event will trigger again.
But everytime i switch forms the form load event will only trigger once. Is there something wrong with my code? I am guesing the Me.Hide() will only hide the previous form and not totally close it.
This is exactly what is happening. The Hide method just hides the form from the user, effectively making it invisible.
What you're looking for is the Close method, which actually closes the form. (Since you are displaying the form using the Show method, you do not need to call Dispose.)
You will, however, not be able to close a form and continue to run code in its methods. So you'll need to reverse the order of the statements in your event handler functions, displaying the other form first and then closing itself. Make them look like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form1.Show()
Me.Close()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
Me.Close()
End Sub
That will do what you want. The Load event will be triggered each time you call the Show method, because you're creating and showing a new form.
It is worth pointing out, though, that you're relying on an unusual characteristic of VB.NET, one that it retains from the older VB languages for backwards compatibility reasons. Instead of referring to an object of your form class (like you would have to do with all other class objects), you are referring to it by the type name (the name of the class itself). You really shouldn't do that, it causes all sorts of headaches and will confuse people reading your code. It is better to just instantiate a new form object, like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim frm As New Form1 ' create a new Form1 object
frm.Show() ' ... and display it
Me.Close()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim frm As New Form1 ' create a new Form2 object
frm.Show() ' ... and display it
Me.Close()
End Sub
When you run this code, you will likely run immediately into another problem: the first time you close Form1, your entire application will quit. This is because, by default for a new project, Form1 is designated as the "Startup form" in your project's properties ("My Project" in the Solution Explorer). You will either have to:
create a third form to use as the "main" form, and set the "Startup form" to this third form, or
change the "Shutdown mode" (also in "My Project") from "When startup form closes" to "When last form closes".
I am guesing the Me.Hide() will only hide the previous form and not totally close it
Yes, it does what it says. If you want to close the form then use Me.Close() instead. The Load event will fire again when you create the new instance.
You'll have to change a setting to ensure that doesn't also close your application. Project + Properties, Application tab, change the Shutdown mode setting to "When last form closes". And put the Me.Close() call after the Show() call.
I also had a similar question. When u .Hide() you are just storing it away in memory somewhere such that when it is re-opened it doesnt have to make a new form just recalls the one from memory hence that method is not called again. You have to destroy the form. So what you can do when navigating to another form is go to that form first and then destroy the current form like so Form2.Show()Me.Close(). Look at my question and my accepted answer. If that works please dont forget to tick this as your accepted answer.
When my form is hidden and reloaded from another form it is not executing the code in the Load event
If MessageBox.Show("Are you sure to close this application?", "Close",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
frmIndex.Show() //the main form
Else
e.Cancel = True
Me.Show() // The form open
End If
The form open going closing and going back to the main/index form. hope it help :) just play with the .show, .hide and e.cancel
I think you using a silly construction, but you should;
Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Form1.close()
End Sub
Use the Shown event.
And use ShowDialog()
Form1.ShowDialog()
Yes. What you are doing is closing the form before it could open up form2.
Instead Of:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Hide()
Form1.Show()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.Hide()
Form2.Show()
End Sub
You Need To Put:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form1.show
Me.hide
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.show
Me.hide
End Sub
If This Helps, Please Reply.
when clicking on the start button in the code below, the form seems to lose focus and I need to click the stop button twice to stop the count. (First click to activate the form, second to click the button) Can someone please explain this behavior or offer a better alternative?
Public Class Form1
Dim testrunning As Boolean
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
testrunning = True
test()
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
testrunning = False
End Sub
Private Sub test()
Dim count As Integer
While testrunning = True
count += 1
TextBox1.Text = count.ToString
System.Threading.Thread.Sleep(100)
Application.DoEvents()
End While
End Sub
End Class
The form doesnt loose focus. The stop button does not gain focus after start-button is clicked- You could give it focus (btnStop.Focus()) in btnStart_Click.
The other problem is that you should change your test-function. It is more like a benchmark.
Read some articles about why using Application.DoEvents could be dangerous and is of poor design in general. It is better to use System.Windows.Forms.Timer or BackgroundWorkers instead.
I think in your code the Application.DoEvents first only let the stop button gain focus and you need a second click to perform the click event.