Clicking on the form causes 'Unable to cast object of type '<Namespace.FormName>' to type 'System.Windows.Forms.Button' - vb.net

I am making a version of the Microsoft game 'Minesweeper'. I make the buttons and labels programmatically and add two handlers for the buttons and one handler for the labels as follows.
AddHandler Newbtn.MouseDown, AddressOf Button_MouseDown
AddHandler Newbtn.MouseUp, AddressOf Button_MouseUp
AddHandler Newlbl.MouseDown, AddressOf Label_MouseDown
then I have three procedures:
Private Sub Button_MouseUp(sender As Button, e As MouseEventArgs) Handles Me.MouseUp
Private Sub Button_MouseDown(sender As Button, e As MouseEventArgs) Handles Me.MouseDown
Private Sub Label_MouseDown(sender As Label, e As MouseEventArgs) Handles Me.MouseClick
Everything works fine until I click outside of the grid of buttons on the form itself, when I get a 'invalidcastexception'. VS2015 goes into a break state. At the top it says:
"Your Application has entered a break state, but there is no code to show because all threads were executing external code(typically system or framework code)."
Additional information: Unable to cast object of type 'Mines.MineSweeperPJS' to type 'System.Windows.Forms.Button'.
Mines is the Namespace.
MineSweeperPJS is the form.
Any suggestions as to the cause of this issue would be greatly appreciated!

The problem is in this part of your event handlers
..... Handles Me.MouseUp
^^^
this means that every mouseup, or mousedown event on your form (Me) are passed to the event handler specified.
I think that you have written this event handler manually changing the parameter sender from Object to Button because if you let the Form Designer use its own template you end up with something like this
Private Sub Button_MouseUp(sender As Object, e As MouseEventArgs) Handles Newbtn.MouseUp
When the form engine calls these event handlers, in response to a Form mousedown or mouseup it passes the reference to the Form itself (Me) and not the reference to a Button. And this is the reason of the invalid cast.
You could remove the ...Handles Me.MouseUp because you have already set up the event handlers using the AddHandler and also restore the sender parameter to be As Object

Related

ResizeEnd event on pressing Maximize button

I am trying to show some hidden columns in a telerik RadGridView when the Form Window is Maximized.
I am aware of Resize Event but since Resize event is fired even before the Form is loaded, I am not using it.
I found that ResizeEnd suits my need but it is not reacting to Maximize button.
Is it possible to fire it with Maximize button.
Thanks.
since Resize event is fired even before the Form is loaded
Then add the handler in FormLoad instead of the designer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddHandler Control.ResizeBegin, AddressOf controlResizeBegin
End Sub
Private Sub controlResizeBegin(sender As Object, e As EventArgs)
End Sub

Catch/Handle Keydown Event From All Control Inside Groupbox

Is there any way to catch all keydown event from any controls like textboxes inside a groupbox using one event handler.?
I try groupbox_keydown, but it's not triggered. I try to make some research in msdn and they say groupbox cannot get focus, so the keydown event will never raised. Is there any workaround for it.?
KeyPreview already set to True.
Edit:
i have some textboxes inside a groupbox. most of them have default or predefined value. what i want is when user have filled the required data and want to skip some textboxes, he just need to press some key like ctrl+enter to excecuting a click on a button in that groupbox or calling a procedure.
This seems to work ok It iterates through the controls collection in the groupbox and adds the .KeyDown event to the example handler.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each ctl As Control In GroupBox1.Controls
AddHandler ctl.KeyDown, AddressOf GroupBox1Controls_KeyDown
Next
End Sub
Private Sub GroupBox1Controls_KeyDown(sender As Object, e As KeyEventArgs)
MessageBox.Show(DirectCast(sender, Control).Name)
End Sub
It may be that there are controls that don't have a .KeyDown event, so you might want to add an empty Try..Catch..End Try block into the code like this, but I wouldn't recommend it as it could hide other problems with the code.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each ctl As Control In GroupBox1.Controls
Try
AddHandler ctl.KeyDown, AddressOf GroupBox1Controls_KeyDown
Catch
End Try
Next
End Sub

VB.NET Button with both MouseMove and Click/MouseClick handlers

I'm attempting to to add both a MouseMove and a Click (or MouseClick) to a button. The end user needs the ability to click the button to add an element, but also the ability to drag the button to a specific location to add an element as well. I have both functions working independently. However, when I add both Handlers, the MouseMove takes precedence, and doesn't allow the Click to happen (attempting to click shows the DragDropEffects.None effect).
Button:
Dim Button As New Button()
'Button Attributes
AddHandler Button.Click, AddressOf Button_Click
AddHandler Button.MouseMove, AddressOf Button_MouseMove
Handlers:
Private Sub Button_MouseMove(sender As Object, e As MouseEventArgs)
Button.DoDragDrop("Button", DragDropEffects.Move)
End Sub
Private Sub Button_Click(sender As Object, e As EventArgs)
'Add Element Function
End Sub
I've also tried it with the MouseClick handler, with the same results:
AddHandler Button.MouseClick, AddressOf Button_MouseClick
Private Sub Button_MouseClick(sender As Object, e As MouseEventArgs)
'Add Element Function
End Sub
1.) What is the reasoning behind the Click/MouseClick not able to fire when a MouseMove is implemented as well?
2.) What is the proper workaround to get both functions usable? Do I need to do MouseDown and MouseUp handlers, and track the distance that the mouse has moved to determine if I clicked or if I am dragging?

User Control Event against Form Control Event

Here is my situation, I have a user control that have the Leave event:
Private Sub MyControl_Leave(sender As Object, e As EventArgs) Handles Me.Leave
If Me.Enabled Then
MsgBox(Property1)
End If
End Sub
I have this to prevent Leave Event from triggering when the control is Disabled.
Then on my form, the control also has its own Leave event because I need to set some Properties that the Leave Event on the User Control needs.
Private Sub myControlOnForm_Leave(sender As Object, e As EventArgs) Handles MyControlOnForm.Leave
MyControlOnForm.Property1 = "value1"
End Sub
What happens is the first event that triggers is the one on the User Control and then the one on the form.
Now my problem is, as the code states above, I need the Form Event to trigger first before the User Control Event.
Is there any work around for this?
The form needs to call a procedure in the user control after it's finished handling the event. Just remove the Handles Me.leave statement, and the private statement. use the sub from your form to call the controls sub which was intended to handle the event.
Note that I've changed sender As object to sender As Mycontrol.
Sub MyControl_Leave(sender As Mycontrol, e As EventArgs)
If Me.Enabled Then
MsgBox(Property1)
End If
End Sub
Code on form
Private Sub myControlOnForm_Leave(sender As Mycontrol, e As EventArgs) Handles MyControlOnForm.Leave
MyControlOnForm.Property1 = "value1"
sender.MyControl_Leave(sender, e)
End Sub
What happens is the first event that triggers is the one on the User Control and then the one on the form.
Now my problem is, as the code states above, I need the Form Event to
trigger first before the User Control Event.
First off, you are using the incorrect term in that problem statement. It is not an event triggering order issue, but rather an issue in order in which the event handlers registered for the UserControl's Leave event execute.
.Net events are a form of syntactic sugar for the invocation of a multicast delegate. When an event is raised a delegate is invoked and the order in which the handlers are executed is the order in which they were added to the delegate. You can gain an understanding of this by working through the various "Walkthrough" tutorials located under Events (Visual Basic).
The Leave event is Raised by calling the Overridable OnLeave method inherited from the Control Class that is in the inheritance tree of the UserControl Class. It is considered bad form for a class to handle its own generated event; the preferred method is Override the method that raise the event.
In your case, you want the form that subscribes to the event to be notified first so that it can modify a property on the UserControl before some it performs some action in response to Leaving the UserControl.
Public Class UserControl1
Protected Overrides Sub OnLeave(e As EventArgs)
MyBase.OnLeave(e) ' this calls the base method that Raises the event
' all event handlers will run before the subsequent code
' executes
If Me.Enabled Then
'do something
End If
End Sub
End Class

How does one override the OnShown Event of a form when creating a form programmatically?

I am trying to get a sound to play when a form is first shown (rather like a standard message box does for want of a better example). If using a standard form added through the designer I would generally do this by overriding the standard onshown event and then go on to call MyBase.OnShown(e)
The problem I've hit now is that the form is being created programmatically (Dim myForm as new Form etc) and as such I seem not to be able to use AddHandler to override this event. I don't doubt that I'm doing this in entirely the wrong way, but I'd appreciate any advice that can be offered. I would prefer advice from the perspective of VB.net, but I can just about muddle through in C#.
Form.OnShown is not an event. Rather, it is a method of the Form class which raises the form's Shown event. Here's the MSDN article that explains the OnShown method:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onshown.aspx
When you are making a derived class by using the form designer, you can override the OnShown method, but when you are simply accessing a form through its public interface, you need to use the Shown event instead. You can add an event handler for that event like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim f As Form1 = New Form1()
AddHandler f.Shown, AddressOf f_Shown
f.Show()
End Sub
Private Sub f_Shown(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Since the form doesn't exist in code, you would actually have to call the event then.
Try writing out the showing code first:
Public Sub form_Showing(ByVal sender As Object, e As EventArgs)
// play sound
End Sub
then when you create your form, you add the handler of the event:
Dim f As New Form
AddHandler f.Shown, AddressOf form_Showing
f.Show()