Preventing an event raised by a built-in function - vb.net

I have this event handler bound to my listview
ListView1.ColumnWidthChanged
And I have this function which alters my columns' dimensions executed right after feeding my list with data.
ListView1.AutoResizeColumns
I want to know if there is a way to suspend VB from firing an event after an automatic sorting ? I mean anything but manual intervention ?
I though about setting a global variable but this takes much work and can be imprecise, also event args parameter doesn't encompass anything implicit that handles a mouse event, Is there any way through ?
This is what I have tried so far about mouse event handling:
Sub listview1mousedown(sender As Object, e As EventArgs) Handles ListView1.MouseMove
AddHandler ListView1.ColumnWidthChanged, AddressOf resizetable
End Sub
Sub listview1mouseup(sender As Object, e As EventArgs) Handles ListView1.MouseLeave
RemoveHandler ListView1.ColumnWidthChanged, AddressOf resizetable
End Sub
Is there any peer solution concerning events triggered by other means rather than mouse ?

Found it finally, ....
Appearently setting cursor event catch doesn't work literally at the header's level, the function doesn't fire any event when the mouse gets off the higher bound of subitem collection's container, therefor I managed te set focus event listener to catch mouse focus on the listview, this is enough user defined behavior for me:
I set:
AddHandler CType(list, ListView).GotFocus, Sub()
AddHandler CType(list, ListView).ColumnWidthChanged, AddressOf resizetable
Debug.Print("handler on")
End Sub
AddHandler CType(list, ListView).LostFocus,Sub()
RemoveHandler CType(list, ListView).ColumnWidthChanged, AddressOf resizetable
Debug.Print("handler off")
End Sub
Then i wrote in my Main():
Public Function resizetable( table As listview, e As columnwidthchangedeventargs)
'... core of the event handler
Debug.Print("Listview column width changed")
End Function
So i ran my app in debug mode and proceeded to adjust my column size manually, then I saw this in my debug console:
handler on
Listview column width changed
handler off
I ran this inside main():
list.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)
Nothing appeared in my output !!!! I think I got it right. thanks to everyone for their deliberate advices.

Related

Remove eventhandler dynamically from a control, from another module/class Visual Basic .NET 2010

I have a function defined in a module which updates the passed byref Combobox and Listbox controls.
for simplicity, say that the definition is as under
Module isDB
private sub PopulateCBO(byref CBO as combobox)
'Here I want to remove SelectedValueChanged and click events temporarily removed using
'removehandler or eventhandler.remove
End Sub
End Module
The control maybe on any form from the project.
To remove an event handler you need a reference to an object that raises an event and a delegate for a method that handles that event. You can't arbitrarily clear all handlers for an event. As such, you cannot remove event handlers in the method you've shown. You'd have to pass the event handler in as well, e.g.
Public Sub ConfigureComboBox(comboBox As ComboBox, onSelectedIndexChanged As EventHandler)
'...
RemoveHandler comboBox.SelectedIndexChanged, onSelectedIndexChanged
End Sub
You would then call that in a form like so:
ConfigureComboBox(ComboBox1, AddressOf ComboBoxes_SelectedIndexChanged)
My around turned out to be fairly simple.
I disabled the comboboox with enabled = false and then in the event handler function, I checked if it is enabled =false
Although removing and adding handlers with all their pros and cons didn't even function :)
What I mean is apart of from alternatives, I still wonder who to do that?
The solutions above did not work on my vb 2010.
Private Sub cboProgram_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboProgram.SelectedIndexChanged
If cboProgram.Enabled = True Then
MsgBox("Enabled, so the real event handler")
Else
MsgBox("Disabled, so a false positive")
End If
End Sub

Equivalent of SelectionChangeCommitted on DateTimePicker?

I have some functions that need to be active only after the Form as loaded.
I had this problem with the ComboBoxes and solved it using SelectionChangeCommitted instead of SelectedValueChanged since the first one only is fired when the user is the one making the change.
Is there any equivalent event for the DateTimepicker.ValueChanged (since this one like the Select.SelectedValueChanged is fired before everything is set)?
This is a pretty common situation.
When, after the first initialization of a Form, a Control's value is modified, the associated Event(s) is/are raises, to notify the change to the subscribers.
The ComboBox SelectionChangeCommitted event is a notable exception: it's used to discriminate between a user direct input and a more generic value change in the selection.
The DateTimepicker control, like most of the other standard controls, doesn't provide a similar event.
Since the Event Handlers subscribed to have attached code that is run when an event is raised, it's a common problem to avoid that these routines are executed when the values of the Controls on a Form are modified by the code that initializes them.
There are different methods to manage the raising of events that can cause unwanted cascading effects at the wrong time. Two of the more common:
Attach the Event Handlers only after the Controls' initialization is completed, using dedicated methods that are delegated to attach/detach the handlers
Make use a boolean Field as a flag to indicate whether the code associated to the Event Handlers should be run when the event is raised.
Both
Attach the Handlers after the initialization procedures:
Public Sub New()
InitializeComponent()
InitializeDataStuff()
InitializeEverythingElse()
AttachHandlers()
End Sub
Private Sub Form_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
RemoveHandlers()
End Sub
Protected Sub AttachHandlers()
Addhandler SomeControl.SomeEvent, AddressOf SomeHandlerMethod
Addhandler SomeOtherControl.SomeOtherEvent, AddressOf SomeOtherHandlerMethod
(...)
End Sub
Protected Sub RemoveHandlers()
Removehandler SomeControl.SomeEvent, AddressOf SomeHandlerMethod
Removehandler SomeOtherControl.SomeOtherEvent, AddressOf SomeOtherHandlerMethod
(...)
End Sub
Use a Boolean Field. The Event Handlers are attached using the Forms' designer:
private DontBotherToRunNow As Boolean = True
Public Sub New()
InitializeComponent()
InitializeDataStuff()
InitializeEverythingElse()
DontBotherToRunNow = False
End Sub
Private Sub DateTimePicker_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
If DontBotherToRunNow Then Return
(...)
'Do something
End Sub

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

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

onClick Event For Picturebox

I have more than 30 picture box in a windows form named
PictureBox1
PictureBox2
PictureBox3
.....so on
I am having to write the same procedure for click function for every single one of them.
I just want to be able to write a single handler that would handle the click events for all the PictureBox and call the same function.
For a rough technical example.. Sorry for the JavaScript Format
picturebox.onclick(){
var a=get_index(this); //gets address of the clicked picturebox
somefunction(a);
}
If you are using the Handles keyword, which is the default, typical way to handle events from controls, you can add multiple event names to the Handles clause, for instance:
Private Sub OnClick(sender As Object, e As EventArgs) Handles PictureBox1.Click, PictureBox2.Click, PictureBox3.Click
' Handles click events from PictureBox1, PictureBox2, and PictureBox3
End Sub
Alternatively, you can declare the event handler method without the Handles clause, and then manually attach it to the events yourself, like this:
Private Sub OnClick(sender As Object, e As EventArgs)
' ...
End Sub
' ...
AddHandler PictureBox1.Click, AddressOf OnClick
AddHandler PictureBox2.Click, AddressOf OnClick
AddHandler PictureBox3.Click, AddressOf OnClick
Or, if you have list of picture box controls, you could add the event handlers in a loop, like this:
Dim myPictureBoxes() As PictureBox = {PictureBox1, PictureBox2, PictureBox3}
For Each i As PictureBox in myPictureBoxes
AddHandler i.Click, AddressOf OnClick
Next
Or, you could access them from your form's Controls collection by name:
For i As Integer = 1 to 30
Dim c As Control = Me.Controls("PictureBox" & i.ToString())
AddHandler c.Click, AddressOf OnClick
Next
Bear in mind, however, if you do manually call AddHandler, you need to also call RemoveHandler to later detach the event handler.
It seems odd, on the surface, to have so many picture boxes like that, though. You may want to consider custom-drawing your content in a single control or look into dynamically loading the controls at run-time.

AddHandler for custom controls error visual studio

I have a MouseEnter event which currently handles some custom controls on my form. The program is a card game. I have a collection (handCards) that gets populated when the user draws a card and then it adds the latest card to the form. This collection holds cards of various custom types, all which inherit from picturebox. Drawing the cards from the deck and adding them to the form works fine. The trouble I am having is that at runtime, after a card is drawn and added to the form, I've created an addhandler line of code to have those cards respond to my MouseEnter event, but my addhandler line of code is telling me that MouseEnter is not an event of object. How can I get around this so that after a card is drawn and added to the form, when the mouse enters the new custom control, my MouseEnter event fires? Here's one of the many things I've tried and what I think should be the simplest and easiest that should work.
deck.DrawCard()
AddHandler handCards(handCards.Count).MouseEnter, AddressOf Cards_MouseEnter
P.S. the MouseEnter event works fine for custom controls that are on the form prior to runtime and all it does is take the image of the control and enlarge it by placing the image to a bigger card on the form.
I am supposing your handCards Collection is an Object Collection. Try casting it to the proper type using CType, something like this:
AddHandler CType(handCards(handCards.Count), PictureBox).MouseEnter, AddressOf Cards_MouseEnter
as #Jason mentioned using the handCards.Count as an index will not work because it is the total number of items where as your index is zero based and will be one less than the Count.
so handCards(handCard.Count) should be handCards(handCards.Count -1)
So this is how I fixed it, in case anyone comes across this post. Made a separate Sub to do the AddHandler. After the program draws a card, it calls upon this method, which then adds the MouseEnter handler I need. The ByVal was key. I originally thought I was supposed to use ByRef, but no. MouseEnter is an event of control, but apparently not Object, so now it works.
Public Sub addHandlers(ByVal inputObject As Control)
AddHandler inputObject.MouseEnter, AddressOf Cards_MouseEnter
End Sub
You could use a generic collection to avoid type casting.
Private handCards As System.Collections.Generic.List(Of PictureBox) _
= New System.Collections.Generic.List(Of PictureBox)(52)
Or you could just use an array of PictureBox objects
Private handCards(5) As PictureBox
Remember that you'll have to initialise the collection or array though, by assigning a PictureBox object to each element of the array.
Now you can add the handler to a PictureBox element of the array since PictureBox derives from Control which implements the MouseEnter event.
deck.DrawCard()
If handCards.Count > 0 andAlso handCards.Last() IsNot Nothing then
AddHandler handCards.Last().MouseEnter, AddressOf Cards_MouseEnter
End If
Your handler will look something like this
Private Function Cards_MouseEnter(sender As Object, e As System.EventArgs) As Object
' Handle mouse events here
End Function
Luckily I was working around and I managed to do successfully this solution.
First Add Event Handler Method Where ever you Wish, For Test I have added this Function at Button_Click
addHandlers(Label1) 'Label one is the control on which I have to attach Mouse Events (Enter,LEave)
Now "addHandlers" function implementation
Public Sub addHandlers(ByVal obj1 As Control)
AddHandler obj1.MouseEnter, AddressOf MouseEventArgs
AddHandler obj1.MouseLeave, AddressOf _MouseLeave
End Sub
Now the Mouse Events:
Private Function _MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) As Object
Try
Me.Cursor = Cursors.Default
Catch ex As Exception
End Try
End Function
Private Function MouseEventArgs(ByVal sender As Object, ByVal e As System.EventArgs) As Object
Try
Me.Cursor = Cursors.Hand
Catch ex As Exception
End Try
End Function