MouseEnter, MouseLeave, etc, Event Handlers on a second PictureBox Fail to Fire - vb.net

I have a large WiseJ vb.net program which has multiple Picturebox controls. An image is loaded into the control on one event, the cursor changes on another etc. Each picturebox use four different events for my functionality. The first picturebox executes the events flawlessly. On the second identically specified picturebox the event handler fails to fire. It won't even execute the breakpoint. I have 8 such picture boxes but only one fires the event handler. I've searched for solutions and tried some but none really address my problem.
I had initially simply copied the working first picturebox code, pasted them, and edited the names to match the next picturebox. This has normally worked well to save time. I then deleted the second picturebox code and went to the page. I double-clicked the offending picture box which generated the click event. The new event still did not fire. I considered a solution which removed the event handler in each picturebox, but frankly, I've added events on pictureboxes so many times and they work fine. I'm guessing something is corrupted behind the scenes but in reviewing the project pages I see no reference to the pictureboxes and am not sure where to look. It's odd that one works fine with all the events but a second fails.
This even works
Private Sub PicFrontLR_Click(sender As Object, e As EventArgs) Handles PicFrontLR.Click
If SpkrDragged = False Then
Cursor = Cursors.Default
LoadSpkrinView(0, "System")
End If
End Sub
This event fails
Private Sub PicFrontC_Click(sender As Object, e As EventArgs) Handles PicFrontC.Click
If SpkrDragged = False Then
Cursor = Cursors.Default
LoadSpkrinView(1, "System")
End If
End Sub
I'm hoping I'm missing something, because one of the solutions involved recreating the page and systematically looking for a failure as I went. This page has a lot of code. Almost done with it and everything else seems to work perfectly.

Well, I figured this one out, mostly. It turns out that a picturebox "apparently" only triggers certain events if there's an image in it. Maybe basic knowledge but I hadn't run into this before. I simply added both a load picture event for the picture box and one for the container. If there's no image the container event fires. If there's an existing picture the picturebox event fires.
One unexplained issue is that the first picture box in a group of eight copied picture boxes, still fires the picturebox event even if there's no picture. As stated the picture box properties are all identical as are the containers. This is what confused me as one event worked and the others did not. Maybe someone can explain.

Related

Keep track of Window being Last Focus

The VB.Net program I am creating dynamically created Panels within a TableLayoutPanel and adds form elements to them. I need to keep track of what the last of these Panels to have focus was, and am hitting a bit of a brick wall.
I have tried creating an event class for when the Panel has focus:
Private Sub Self_GotFocus(ByVal sender As Object, ByVal e As EventArgs) Handles Me.GotFocus
GlobalController.Focus_Target = Me.Name
End Sub
The classes for each Panel Inherit from Windows.Forms.FlowLayoutPanel, which I why I have the call being Me.GotFocus. Additionally, the GlobalController class is just a class meant to hold global variables for the program.
Now the issue I am having, is that this event only seems to trigger when I actually am deleting the panel. When the panel is created, if I click on it, or any of it's form elements, the event never gets triggered (I debugged the program with a breakpoint).
I can't exactly figure out why this only triggers when I go to delete the panel, and not at any other time. Is there another event I should be using instead of GotFocus?
Use .Enter event in your panel since GotFocus is related only to focused control (not it's parent), mostly when UICues is set.
See MSDN GotFocus

Nothing works anymore after building project in vb.net

I was going to build my project when i noticed i didn't put an icon,
and since i couldn't access the icon value of the original form because i used a theme i C+X the container and access it from the grey form, change it, C+V the container, built the project.
Nothing changed, all the name of the buttons and stuff are the same, but i feel like nothing is connected to the code anymore, i don't know what happened, i just recently got re-interested into coding, and i have no idea what to do, i tried some things but nothing worked, so here i am, desperate (i spent 3 days on this, i'm REALLY starting from bottom)
link to the project: http://www.mediafire.com/file/2zrbe32lzpx2qhz/SchedulerProjectVBNET.rar
Thanks in advance
It sounds like you have lost all the Handles clauses off your event handlers. As an example, if you add a Button to your form and double-click it, you will get a Click event handler like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Note the Handles clause at the end, which is what connects the code to the event of the control. If you cut that Button from your form to the Clipboard then it no longer exists as part of the form, so that Handles clause will be automatically removed. If you paste the Button back onto the form, the Handles clause is not restored, so the method no longer handles the event.
If that's what has happened - which you can easily check just by looking at the code - then you need to restore all those Handles clauses. You can do that manually, i.e. write them all yourself in the code window, or you can have the designer regenerate them for you. To do the latter, select a control in the designer, open the Properties window, click the Events button, select the desired event and then select the appropriate method from the drop-down list.
Note that you can also double-click an event there to generate a new event handler, which can be useful for handling events other than the default event. You can generate a handler for the default event simply by double-clicking the control.

What causes Visual Studio To Change Control Names?

In one project, the names of my GUI controls are being changed at compile time.
Say, for example, I have a Label control named **lblRow0Col1".
I noticed my code was failing to find the control by name:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each ctrl As Control In Controls ' .Find("Label*", False)
If ctrl.Name = "lblRow0Col1" Then
ctrl.Text = DateTime.Now.ToShortDateString()
End If
Next
End Sub
So, I stepped through that routine and found the control I needed had been renamed to what looks like a GUI string.
lbl.Name = "07178f89-6fdd-47c7-9f84-d4d661df7554"
I created a test project to see what was going on, but this is not happening in the test project.
Is there a VS setting that tells the compiler to scramble the control names?
How do I stop this behavior?
OK, I’ve been looking at the code for that routine that populates a "details view" screen.
Before, I was filling the detail screen as soon as the Inventory Item variable changed.
I got to thinking that people rarely view the details screen, so why not just populate it after the screen was displayed? I had an event for “after displayed”, so I moved it there.
Well, I just moved it back ...and the odd behavior went away.
I don’t know what the issue was that caused that to happen, though.
The Label controls should have already been generated, but it acts like they were not until the tab screen they were on was selected.
So, there's an answer, but I'd rather someone explain to me what I did wrong.

VB.net event handler abort when it is fired again

I have an application written in VB.net. In that application I have multiple forms and lots of functionality. The form the application starts with, is some kind of menu. In the background, I have a list of menu items that a user can see and use to open a new form. It is possible to search through all those menu items via a textbox where you can fill in some text and the code then compares all the menu items names to the filled in text and shows the result. This event is fired on every textchanged event of this textbox. But if the user types in a name that occures a lot (like à 100 times or so) the view takes some time (3 to 5 sec) to display all those results. Now I would like to know if it is possible to abort the first event handler if the same event is called again. That means that if I am typing in the textbox and for the first 4 or 5 letters almost all menu items are matches, so I want to abort that search and start a new one right away. Is there any way to detect that the same event is called again and abort the currect one to make the new one start right away?
Thanks in advance for reading this and helping me solve this problem!
In order to accomplish this, you are going to have to do the work in a separate thread. The primary reason for that is that WinForms are single-threaded. All UI-related events in a WinForm are handled on the same UI thread. As such, there is no way for the TextChanged event to fire again while you are still in the middle of processing the previous event. The UI will be locked up until the first event if finished processing.
However, if you do all of the menu-filtering work in another thread, then your UI will be freed-up to react to user input while you are doing the work. Then your TextChanged event will be allowed to fire before the previous one is done processing.
The easiest way to implement multi-threading in a WinForm project is to use the BackgroundWorker component. You can find it in the form-designer tool box. Luckily, the BackgroundWorker component has some properties and methods which are useful for implementing the cancellation as you described.
For instance, here's a very simple example. In this example, every time the text in TextBox is changed, it starts BackgroundWorker1 performing some work. The work that it does is to simply wait two seconds and then copy the contents of TextBox1 to TextBox2. If the text changes again before those two seconds are complete, it cancels the bacground work and starts it again from the beginning.
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If BackgroundWorker1.IsBusy Then
BackgroundWorker1.CancelAsync()
Else
BackgroundWorker1.RunWorkerAsync()
End If
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For i As Integer = 1 To 20
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
Exit Sub
End If
Thread.Sleep(100)
Next
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If e.Cancelled Then
BackgroundWorker1.RunWorkerAsync()
Else
TextBox2.Text = TextBox1.Text
End If
End Sub
In order for the above example to work, the BackgroundWorker1.WorkerSupportsCancellation property must be set to True.
As you can see, when the text changes, it simply checks the IsBusy property, which determines whether or not the background thread is still working from a previous event. If it is, it cancels it. If it's not, it starts it.
All of the work which needs to be done on the separate thread is done inside the background worker's DoWork event handler. As it is doing the work, it needs to periodically check whether or not it has been canceled. If it has been canceled, it needs to stop what it's doing and set the Cancel property of the event args to indicate that it is stopping because it was canceled.
Once the background work is done, (whether by cancellation or by completing its task), the background worker raises the RunWorkerCompleted event. The event args for that event have a Cancelled property which indicates whether or not the work completed because it had been canceled prematurely. In the example, if it was canceled, it simply restarts the work from the beginning.
For what it's worth, all of this would be moot if there was some way for you to speed up the menu-filtering algorithm to the point where it's near instantaneous. It may be possible to do that by indexing your menus in something like a suffix array.
Try to add a condition. In your search method, if your text length exceeds some value, call the same event again (like in recursive methods). It should works.
Regards,
Daniel
add some condition on length of search string...like on its Length should be 5 or more
OR maximum results shown at one time should be limited.

Why doesn't a MsgBox trigger a lost focus event VB.net?

I have a timer that each time displays a message box saying "Hello." I also have the code configured so whenever the window loses focus, it should stop the timer that keeps the boxes coming. However, they keep coming.
I have tried a similar thing in a similar program with way too long of code to post here, but what it did was it paused the first time, stop the timer, and when the timer was stopped again, it didn't work correctly. There was also some other code there that had a random element, that displayed a different prompt when a certain number was generated, but once it was generated, it kept using that same different prompt every time.
Is this a error of not enough time to process all the code and it "overlaps" some? I can delay the timer without that much different effects, but I think that my [lower end] CPU that it is running this program on, that with 1.6 GHz that it could handle a timer with a few message boxes. Though, VS is running at the same time, but I shouldn't have to export my code and close VS everytime that I need to test it.
If the problem is not enough time, is there a way that I can prevent my program from "multithreading" or whatever it is doing? It seems like a weird problem, but computers are very weird too. :P
Edit:
By "Focus" I mean the selected window that is the most apparent. For example, my browser is now "focused." I have been informed that the correct term is "selected." I must have been using the wrong type of event trigger... :P
It doesn't generate a lost-focus event because the form doesn't have the focus in the first place. A control on the form always gets the focus, like a Button or TextBox. You could use the Deactivate event instead.
Or just not display the message box when the Tick event fires again. Roughly:
Private ShowingMsgBox As Boolean
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'' Do stuff
''
If Not ShowingMsgBox Then
ShowingMsgBox = True
MsgBox("yada")
ShowingMsgBox = False
End If
End Sub
The underlying reason for this behavior is that MsgBox pumps a message loop. It keeps normal Windows messages getting delivered, like WM_PAINT that keeps the windows painted. And WM_TIMER, the one that generates the Tick event. The only kind of messages that it blocks are input events, mouse and keyboard messages. Otherwise the reason that Application.DoEvents() is so very dangerous. It does the same thing as MsgBox() does, without disabling input.
Create a new project with a Timer (Timer1) and write this code:
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
If (Me.Focused) Then
MessageBox.Show("Hello")
End If
End Sub
If you put the mouse over your form, you would see that a message box will popup after the given Interval is over. If you don't click on the accept button and keep the mouse on the form, you would see that no further messages appear: Me.Focus is False. If you click on the accept button, the messages would start poping up; you don't even need to select the form (the focus is transferred automatically from the MessageBox to the Form).
Summary: the MessageBox does make the Form to lose the focus, although it is a kind of a "tricky" lost as far as will automatically come back after clicking on the accept button.
UPDATE: the proposed configuration does trigger a LostFocus event of the form:
Private Sub Form1_LostFocus(sender As Object, e As System.EventArgs) Handles Me.LostFocus
MsgBox("lost")
End Sub
Unlikely the other answers/comments, what I understood from your question is that you want to know the reason and if this is a normal behaviour, rather than getting a working solution to make the form to lose the focus (you are not even describing the exact conditions under which you want this to happen).