Allowing two windows from the same APP to move - vb.net

I'm making a VB.net application. I have a dialog that pops up at some points. It is set as TopMost. The problem is, when it pops up, you can't move the main form. How can I make it so it shows and is usable while allowing the main form to continue to be usable?

It sounds like you're calling ShowDialog(), but the behaviour you describe sounds like you want to call Show() instead (of course, this'll mean that you will not get the DialogResult, nor will the calling code block, but this allows the parent window message loop to handle things like moving the window)

Related

Debugging problem in VB.Net with Windows Forms with losing events

We have a huge application that runs through a mass of code for every click you do. In one specific case, where you have a specific control in plain sight (so that the events are firing) and you load some special data into it and then click on the new button the form loses some events, like the closing event (you cannot close the form anymore and stop points in debug mode are not triggered) and one validating of a ComboBox that is really needed for the program. The only thing you can do when you get this kind of error is to restart the application to get out of this subform. But I tested it for 2 days now and even when I activate all points in the 'Exception Settings' I don't get any exceptions. The form (and other controls) are not losing ALL events. The resize, for example, still works. Even a specifically called AddHandler is not firing. Can you iterate somehow through the EventHandlerList? Or is there any way to test WHERE the event dies? Somehow any ideas on how to debug such a problem?

Parent form and child User Control communication in WinForms

I have my form with a menu bar and space underneath to display my controls. One of the buttons in my menu bar is suppose to be a print button that prints a graph that's currently in a User Control I display in the form. If the graph was on the form in the print button's eventhandler I could just simply call
graph.printing.print(true)
which isn't going to work in my case since the graph is in the control and not the form.
How do I communicate with a User Control from the containing form and access or pass its variables when needed? I also have a status bar on the bottom of the form which would also need to get updated from the User Control, but I'll be able to deal with that if I got help with just this one part. Please bear in mind, I also have another User Control I'm going to add to the form which will also contain a graph which will need the same treatment as the other graph on the first control when the print button is pressed. I plan on swapping these two out so I have one form displaying one control at a time.
I got this idea from this answer: https://stackoverflow.com/a/18191630/2567273 but after further research I can't find anyone asking about the actual communication process between a form and the control it contains.
I think this answer is close to what I'm looking for, but I think it's leading me down the path to using panels instead of User Controls.
After typing this I noticed the closest answer to my question may be this, but that question has the child raising events and the parent responding while I have the parent raising the event and the parent has to get information from the child.
One way to think about this is Roles. Presumably you built this UserControl to handle the management of the data related to the graphs. As such you can think of them in the Role of a Graphs Specialist . Once you do that, printing them is actually just one more thing it should perhaps do.
The form on the other hand, is not special just because it happens to get receive the command from the user to print. Its role in this might simply to be to know which usercontrol to contact and which method to invoke:
Sub PrintGraphMenuClick....
Select Case something ' determinant as to which UC to contact
Case operation.Foo
ucFoo.PrintGraph
Case operation.Bar
ucBar.PrintGraph
Other menu options like Clear, NewGraph, Save and whatever else there is somewhat the same way. The Form's Role here may be to receive the command from the user and pass it along to the right control, invoking the correct right method and passing the correct parameters - that is not a trivial task.
Of course, rather than a MainMenu, the usercontols could alternatively implement a ContextMenu and even receive those commands directly.
Very often offloading an operation to something else results in so many properties, filenames, streams etc having to be moved from here to there that it becomes burdensome. In this case it is not like the MainForm has some special ability regarding printers that the UserControl cannot handle.
There is only one right solution:
1) Add an event to your user control.
2) Raise the event when the particular "thing" happens in the user control.
3) Attach a handler to the event in Form code.
4) Add code to update the bottom bar in the event handler.

Let a Form stay on top even if ToggleDesktop() (shell32.dll) is called

is there anyway to capture and cancel or do something like me.activate when the show desktop event is triggered and make my form visible?
note:
The show desktop event is triggered by another app which is installed in some of my users pc. I am not trying to make my form always on top of other open windows.
Thanks in advance.
Alright, you mean to let your form stay on TopMost even if ToggleDesktop() in shell32.dll is executed.
By far I can say: there is none. They tried to experiment at codeguru but it seems there were no successfully results.

Keep form on top of another form in modal fashion, but continue execution

I have a form in a vb.net windows form application called PolicyRefreshStatus.vb that has a ProgressBar control on it. From the main form called EditPolicy.vb I need to show PolicyRefreshStatus.vb over top of EditPolicy.vb - but the way things are wired I'm controlling the the ProgressBar and it's steps from logic inside EditPolicy.vb.
If I display the PolicyRefreshStatus.vb bar using the .show() method things work fine. The problem is if the user clicks back on the main form then PolicyRefreshStatus.vb losses focus. If I show PolicyRefreshStatus.vb as a modal form using .ShowDialog() then execution halts in EditPolicy.vb after the .ShowDialog() statement.
so for example in the code:
mPolicyRefreshStatus = New PolicyRefreshStatus
mPolicyRefreshStatus.pbMax = mPolicy.ClaimsUpdateMax
mPolicyRefreshStatus.ShowDialog()
mPolicy.UpdateFromFIS()
The line mPolicy.UpdateFromFIS() never executes because it's waiting for the PolicyRefreshStatus form to close.
How can I show PolicyRefreshStatus in a modal form but let execution continue in EditPolicy.vb?
You've got a couple of related options.
This first is to pass the unit of work to the progress bar in the form of a delegate or a class implementing an Interface. Something like this (not checked for correctness, just a rough example):
mPolicyRefreshStatus = New PolicyRefreshStatus
mPolicyRefreshStatus.pbMax = mPolicy.ClaimsUpdateMax
mPolicyRefreshStatus.UnitOfWork = AddressOf(mPolicy.UpdateFromFIS())
mPolicyRefreshStatus.ShowDialog()
Then within the progress form you can call back to the routine that actually does the work.
Another approach is to define events on your ProgressForm and then the owning/launching object can handle those events to do the work in. With this option you can create a fairly detailed set of events to be able to handle incremental work or cancels, but the concept is the same, youu are calling back from the progress form into launcher to perform the actual business logic.
You cannot show the form modally and let your routine continue. You must show the form Non-modally and then do your other stuff, closing the form when you've finished. Maybe a loop until the task has finished?
Using Show() with a parent form parameter will give you better usability. More like a tool window.

Add a spinning wheel while application is searching database

I have an application that searches in a database for some information.
Since the database is quite big, it sometimes takes a lot of time before the application returns the results to the interface.
I want to add some sort of spinning wheel to inform the user that the application is still searching the database and did not freeze. Once the results are returned, the wheel should disappear.
Any idea how to do this or is there a good tutorial explaining how to do this?
Have you considered changing the mouse pointer to the hourglass as this would be extremely simple to implement:
Me.Cursor = Cursors.WaitCursor
...Do your DB calls here...
Me.Cursor = Cursors.Default
However, I would agree that display a 'spinning wheel' is probably a little more user friendly and definately a lot more obvious. So, first get hold of an animated gif that suits your needs. Then create a form that has a picture box containing the image.
Once you have that you can show the form to the user and in the background do the DB work, once this has completed close the form.
Another alternative would be to use a rolling progress bar instead, so when it reaches 100% it cycles around again and keeps going until you close it.
EDIT:
One thing that I forgot to mention is that you will have to handle exception conditions. Lets say you set the cursor to wait, then an error occurs. The exception may bypass the code that resets everything. This leaves the user with a changed cursor and no means of changing it.
When I have done this kind of thing I have typically created a disposable WaitCursor class and then used something like this:
Using myWaitCursor As WaitCursor = New WaitCursor
...do something...
End Using
In the Dispose of the WaitCursor class you set the cursor back to default. The same would apply if you went down the route of using a form with an image or progress bar.
Find an animated gif of such a spinner, like this one. Put it in a PictureBox, set its Visible property to True when you start the job. Beware that you'll have to run the query in a worker thread to keep the animation alive and the user interface responsive. The BackgroundWorker class is good for that.
You could use the Environments Default wait cursor, which for Vista/7 is a circle with the outside spinning, or the XP tumbling hourglass.
You could launch your DB access on a BackgroundWorker and show an animated control such as a Marquee progress bar, or you could show a custom animation to show Busy status.