So, I have a UserControl where I have a handle for button click:
Private Sub Forward_Click(sender As Object, e As EventArgs) Handles Forward.Click
and a second button click:
Private Sub back_Click(sender As Object, e As EventArgs) Handles Back.Click
I have another handle for a mouse click on the userControl:
Private Sub UserControl_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
Depending on the condition, I want to raise event of one of the button clicks from this sub function. All these handles are in the same UserControl Class. How would it be implementable.
You can check for which button was clicked by comparing e.Button to MouseButton.Left or MouseButton.Right. This would make sure that you only run code when the left mouse button was clicked.
If e.Button = MouseButtons.Left Then
'Any user code here
End If
You can call another event handler by using its method name just like calling any other method.
Forward_Click(Me, Nothing)
To put it all together it would look something like this.
Private Sub UserControl1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
If e.Button = MouseButtons.Left Then
Forward_Click(Me, Nothing)
ElseIf e.Button = MouseButtons.Right Then
Back_Click(Me, Nothing)
End If
End Sub
Your conditions may be different as this is just an example. It also may not be "Best Practice" but I am not here to argue what "Best Practice" is. This is a working example to answer your question. Hope it helps.
Related
I am creating a game in VB and I have 4 images and 4 buttons down each image, of course right now I can click the button with the mouse to pick an option but I want to type the letter "A", "S", "D","F" of the keyboard to activate each button.
How can you do this in VB?
My current code for the button is the following
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
My.Computer.Audio.Stop()
My.Computer.Audio.Play ("D:\VisualStudio\DIFgame\sounds\correctSound.wav") 'correct sound audio
Cara.Visible = True 'show face
End Sub
You should set the KeyPreview property (documentation) of the Form to True, then in the Form's KeyDown event (documentation) you would check the incoming KeyCode. If it matches one of your desired shortcuts, then raise the event of the button.
Something like:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If (e.KeyCode = Keys.A) Then
RaiseEvent Button1.Click
End If
End Sub
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.
My codes:
Me.KeyPreview = True
...
Private Sub Form_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
If e.Button = Windows.Forms.MouseButtons.Right Then
MsgBox("Right Mouse clicked.")
End If
End Sub
Try to capture mouse right click, but not work.
Any suggestions welcomed. Thanks
As other mention in comments your code seems right, but will only work on plain form. To overcome that you can join events.
Private Sub Form_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick, Button1.MouseClick, Control1.MouseClick, AnyOtherControl.MouseClick
If e.Button = Windows.Forms.MouseButtons.Right Then
MsgBox("Right Mouse clicked.")
End If
End Sub
Please replace Control names you want your event to fire on in this code:
Handles MyBase.MouseClick, Button1.MouseClick, Control1.MouseClick, AnyOtherControl.MouseClick
I'm guessing you are using any of container controls which fill up most of your form. If you want your event to work with them you need to add them to your event.
Finally there is also matter of DoubleClick which won't fire above event. To overcome it all you need to do is change MouseClick to MouseDown
I have created a game in visual basic, and have decided to expand by adding multiple rooms on the game. Each room will be a panel that shows when the user enters a certain area. To start, I created a class that inherits panel properties, then added it to my main Form. I then added all the items to the panel controls. My issue is that i cannot control the player when it is in the panel controls. I have tried all sorts, but couldn't get it to work.
I did some reading and found that panel does not come with keyUp() and keyDown() events. However, I would like to know if there is a way round this.
Thanks in advance!
Code of mainRoom() class (my panel):
Public Class mainRoom
Inherits Panel
Sub New()
With Me
.SetBounds(0, 0, Form1.Width, Form1.Height)
.SendToBack()
End With
End Sub
Public Sub mainRoom_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
e.Graphics.FillRectangle(Brushes.DarkOrange, block)
End Sub
End Class
In main form class:
Sub setMap()
main = New mainRoom()
Me.Controls.Add(main)
End Sub
You can set the KeyPreview=True on the main form, and then handle the key up/down events from the form:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
'key down code.
e.Handled = True
End Sub
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles MyBase.KeyUp
'key up code.
e.Handled = True
End Sub
Note: if you don't want other controls' key up/down event handlers to fire after your form event handlers do, then set e.Handled=True as I have in the above example.
See MSDN for more info on KeyPreview.
BEWARE - when moving (cut/paste) existing controls via the IDE from a form into a new panel control, the event handlers are not carried across as they become children of the parent control (the new panel). So this happens:
Private Sub Button1_Click(sender As Object, e As EventArgs)
Add the event handlers back and don't spend an age googling why keypress events suddenly stop firing in panels ...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
If e.Control Then
MessageBox.Show("aaaa")
End If
End Sub
As you can see, my form will check for when the control key is pressed down.
But it doesn't work. Why?
I am not near a computer now so I can't test this, but when I have wanted to get key events on a form before, I would set Form1.KeyPreview to True (or something similar).
That works fine. I assume you have other controls in your form. One of them will get the focus, never the form. Keyboard input only goes to the control with the focus.
You can set the form's KeyPreview property to True. The Winforms' way is to override the ProcessCmdKey() method.
You need to set KeyPreview to true when loading the form, it should work then
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.KeyPreview = True
End Sub
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
MsgBox(e.KeyChar)
End Sub