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
Related
I'm struggling to make the MSDN code sample for the Control.VisibleChanged event work: I don't see the MsgBox.
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs)
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub AddVisibleChangedEventHandler()
AddHandler myLabel.VisibleChanged, AddressOf Label_VisibleChanged
End Sub 'AddVisibleChangedEventHandler
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
You need to "wire up" the events to the event handlers.
To start with, to get the code in HideLabel_Click to be called you need it to respond to a click on the button named "HideLabel".
There are two ways to do that: you can use AddHandler or the Handles clause.
To demonstrate the latter:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub myLabel_VisibleChanged(sender As Object, e As EventArgs) Handles myLabel.VisibleChanged
MessageBox.Show("Visible change event raised!!!")
End Sub
End Class
However, you will notice that the message is shown even before the form appears. That is because of what goes on behind the scenes to create the form.
To avoid that happening, you can add the handler after the form has been shown:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub myLabel_VisibleChanged(sender As Object, e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AddHandler myLabel.VisibleChanged, AddressOf myLabel_VisibleChanged
End Sub
End Class
Another way, in VB2015 and later, is to use a "lambda expression" instead of a separate method, although then you cannot disassociate the handler from the event with RemoveHandler:
Option Strict On
Public Class Form1
Private Sub HideLabel_Click(sender As Object, e As EventArgs) Handles HideLabel.Click
myLabel.Visible = False
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AddHandler myLabel.VisibleChanged, Sub() MessageBox.Show("Visible change event raised!!!")
End Sub
End Class
Craig was kind enough to [and I quote verbatim] call attention to the importance of Option Strict when you add handlers manually using AddHandler. Without it, the "relaxed delegate convention" may allow adding handlers which don't exactly match the event signature that you won't be able to remove later.
Having said that, Option Strict On isn't a complete safeguard: notice how my last example compiles and works even with the wrong method signature for the handler.
[I suspect that the MSDN code sample was first created in C# as part of a larger example, so some parts have been lost in the translation and excerption.]
I get this is old but came across this post when looking for more information on VisibleChanged and couldn't help but notice that the accept answer may be misleading. If you are using a designer to create your Form and place objects on it, then the accepted answer will be fine. In fact you can get rid of the addHandler because the designer handles that for you. All you would need to do is use a handles clause with your label.
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs) Handles myLabel.VisibleChanged
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Where the issue lies with the accepted answer is if you arn't using a designer. Adding handle clauses to "wire up" simply won't work (we can make it work and if anyone is interested in that I'll be happy to post a code snippet of that, but it's not how the accepted answer lays it out). In your case all you need to do is call AddVisibleChangedEventHandler() to set up the handler. that's it. you could have done this by calling it in MyBase.Load
Private Sub Load_Form(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
AddVisibleChangedEventHandler()
End Sub
Private Sub Button_HideLabel(ByVal sender As Object, ByVal e As EventArgs)
myLabel.Visible = False
End Sub 'Button_HideLabel
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Private Sub AddVisibleChangedEventHandler()
AddHandler myLabel.VisibleChanged, AddressOf Label_VisibleChanged
End Sub
Once again I know this is dated but couldn't help but notice that (more or less assuming) that you are trying to get a msgBox to appear when you click a label. That is you click a label and then toggled the visibility of another label. The other label is the one where the event handler is on for visibility change. So that inevitably gets called when clicking the original label. IF you only want this msgBox to appear when clicking that label and not when the form loads as well, you should change the addHandler statement so that you are adding a handler on the click event.
Private Sub Load_Form(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
AddVisibleChangedEventHandler()
End Sub
Private Sub Label_VisibleChanged(ByVal sender As Object, ByVal e As EventArgs)
MessageBox.Show("Visible change event raised!!!")
End Sub 'Label_VisibleChanged
Private Sub AddVisibleChangedEventHandler()
AddHandler otherLabel.Click, AddressOf Label_VisibleChanged
End Sub 'AddVisibleChangedEventHandler
Also Option Strict On has nothing to do with addhandler (From my understanding, could be wrong. please enlighten me if that is the case). Option Strict On is only checking to see that you arn't implicitly typecasting. So for example:
Dim a As Double
Dim b As Integer
a = 10
b = a
results in an error when Option Strict is On but is totally legal if it is off. So in the case of you leaving off the handles clause, you'll never be implicitly typecasting and therefore is not needed.
Hope this helps anyone who sees this question
i need to create system tray "panel" like Windows Media Player.
(not icon only, but complette form with buttons, images, etc.)
Here is wmp screenshot:
Is it possible in VB.NET & Win 10?
Thanks and sorry for my english.. :)
You actually can do kind of a "tray panel", and it isn't quite difficult. Just create a Form Object and set its FormBorderStyle property to None, which will allow you to create your custom border. Then, do the following:
Public Class Form1
Public Timer1 As New Timer
Private Sub Form1_Load(sender as Object, e as Eventargs) Handles MyBase.Load
Timer1.Interval = 1
End Sub
Private Sub Form1_MouseDown(sender as Object, e as MouseEventargs)
Timer1.Start()
End Sub
Private Sub Form1_MouseUp(sender as Object, e as MouseEventargs)
Timer1.Stop()
End Sub
Private Sub Timer1_Tick(sender as Object, e as Eventargs)
Me.Location = New Point(Me.Cursor.Position.X - (Me.Cursor.Position.X - Me.Location.X), Me.Cursor.Position.Y - (Me.Cursor.Position.Y - Me.Location.Y))
End Sub
End Class
Once you've done that (I'm not sure it will work directly, try a bit and it should), enjoy designing the GUI... ;-)
Hope this helps and by the way, your english is better than you think!
Currently, I have this, on my Form.vb:
Private Sub txtBox1_Leave(sender As Control, e As EventArgs) Handles txtBox1.Leave
'Some code
End Sub
...
Private Sub txtBox10_Leave(sender As Control, e As EventArgs) Handles txtBox10.Leave
'Some code
End Sub
The thing that bothers me is: All those events are doing the same thing. Is it possible to programatically have a list of the relevant controls and iterate through them, adding such events? This would allow me to reduce the amount of code in my application / coding effort. Something like:
For Each c As Control in listOfControls
'Add event for c here which calls method
Next
I really think there is a simple way of doing that but everything I've tried so far (such as AddHandler) did not work. Any ideas?
Thank you
Yes it is possible and quite simple, create a method that will add the requested event to the Control, pass an array of controls to that method before the form loads:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' add events to all requested controls
AddEvent(New Control() {TextBox1, TextBox2, TextBox3, Button1})
End Sub
Public Sub AddEvent(ByVal myControls() As Control)
For Each c As Control In myControls
AddHandler c.Leave, AddressOf Control_Leave
Next
End Sub
Private Sub Control_Leave(sender As Object, e As EventArgs)
MsgBox("Control is not in focus")
End Sub
End Class
Im making a stop watch to measure how long it takes for certain weapons to empty their clip in CS:GO. I have the stopwatch programmed, but it only seems to work if im clicking within the bounds of the window. If its possible, does anyone know how to make it able to start/stop even while in another program? Ill post the code below.
Public Class Form1
Dim WithEvents timer As New Timer
Dim milliseconds As Integer
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
Timer1.Start()
End Sub
Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
Timer1.Stop()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
totalTime.Text = 0.0
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
totalTime.Text = totalTime.Text + 0.01
End Sub
End Class
The MouseDown and MouseUp events only happen when the mouse clicks within your application so you can't use them as events to track the time the mouse is held down in another application.
You may be able to do what you want using a global mouse hook or by looking at windows messages such as the Mouse Down and Mouse Up messages
In Microsoft Access, when you click on a label, the textbox associated with that label gets the focus. As far as I can tell, VB.NET does not have this same functionality. I know I can always add something in to the click event of the label, like so...
TextBox1.Focus()
But I have dozens of fields on the form, and it would make it so much easier if I did not need to add this to the click event of each label.
I guess it would be possible to make an event for all labels that forces a tab to the next control, and assuming that I have the Tab indices set up correctly, then this would work. The problem would occur when adding new fields to the form, in which case all tab indices would need re-verified.
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click
'code to tab to next field...
End Sub
Is there any easier way?
First, set the controls' TabIndex orders on your form then use this code:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each c As Control In Me.Controls
If TypeOf c Is Label Then AddHandler c.Click, AddressOf Label_Click
Next
End Sub
Private Sub Label_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Me.SelectNextControl(sender, True, True, True, True)
End Sub
End Class
Now whenever you click on a label, the following control in the order will be focused.
How about creating a dictionary where the label is the key and the control to focus is the value, then add a Click event handler to all of the label in the Dictionary. Everytime you add a label/control 'all' you need to do is add another KeyValuePair to the Dictionary
Simple Example:
Public Class Form1
Protected Friend DicLabelToControl As Dictionary(Of Label, Control)
Protected Friend Sub InitLabelDic()
DicLabelToControl = New Dictionary(Of Label, Control) From {{Label1, TextBox1}, {Label2, TextBox2}}
End Sub
Protected Friend Sub AddClickEventsToLabels()
For Each lb As Label In DicLabelToControl.Keys
AddHandler lb.Click, AddressOf HandleLabelClick
Next
End Sub
Private Sub HandleLabelClick(sender As Object, e As EventArgs)
DicLabelToControl(CType(sender, Label)).Focus()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitLabelDic()
AddClickEventsToLabels()
End Sub
End Class