Small flickering when showing a modal dialog in .NET - c#

I'm experiencing a annoying issue in my .NET Windows Forms application.
I have a MainForm (A) and a progress form (B) that is shown modal when I start a long operation.
When the operation finishes, and B is closed, it seems that the window that is behind my application (is occurs usually with Skype) is brought to front during few milliseconds and, then my application is activated normally.
Is only a small flickering, but annoying. Here I write some tips that could help to find the solution:
I called showDialog without IWin32Window, but I added it without success result.
I closed B using Close(), then I tried Hide() and then Close() but did not help.
The code that executes the ShowDialog() is invoked from the UI thread, so it don't seem to be a threading issue.
Any clue would be appreciated. Thanks in advance.

I was experiencing these same symptoms and it was driving me crazy.
I finally discovered the problem was that i was calling this.Dispose() instead of this.Close() to close the modal window I'm not sure why I called this.Dispose() in the first place.
After switching methods, the problem went away.
I realize that this thread is old and this is not the cause of your problem, i am just trying to help anyone else who made the same mistake that I did.

Check if you DON'T call Hide or Close. The only way to avoid flickering is DialogResult.
Upd:
this.DialogResult = DialogResult.Ok
Check handlers OnFormClosing and etc. They might containt wrong method call.
The little trick is to set Owner explicitly
_dialog.Owner = this;
_dialog.ShowDialog();
People who are editing the post - _dialog.ShowDialog(this) works a bit different.
Look at owner = ((Control) owner).TopLevelControlInternal; in decompiled code
Edited by someone:
Or...
_dialog.ShowDialog(this);
These calls are identical according to MSDN

Do not call Close for modal window (it will not be disposed and memory leak is guaranteed)
Set this.DialogResult = DialogResult.OK
Call Dispose() from the parent, NEVER from the form you are closing
Remember of disposing all of your components holding by the form IContainer in Dispose(bool) (VS Designer implementation of Dispose(bool) is usually not enough not to have memory leaks)

In my case I was also facing the same issue in my VB.Net winform application but a bit different scenario.
I was having a user control which opens up a dialog using showdialog() say dialog1 and on filling some data it hides dialog1 and opens up dialog2 using showdialog() again.
In the process of hiding dialog1 and showing dialog2 flickering occurs and it shows the window at background for a moment.
After trying so many solutions and workarounds none work for me. I found one workaround myself which might help others.
To hide dialog1 I was using Me.Hide(), The solution is to change the opacity of form instead of calling Hide() method.
'Me.Hide()
Me.Opacity = 0
After this workaround the application works fine without any flickering issue.
PS: The above code lines are in VB.Net but enough for a .Net winform application developer to get the idea for fixing this issue.

Okay,
it sounds like
In the main window a user starts a long operation
You display a progress modal window
Operation completes you close the progress window
Your main window doesn't display immediately. Instead something behind it shows through for a second or less.
Your main window completes it's redraw operation and is 100% visible.
This happens more often when you have applications such as Skype running.
If that's the case there are many different possible causes. For example, your video drivers might have a bug in them causing delays in off screen compositing under certain conditions.
The system itself might even be experiencing a blocking CPU operation at the moment. This is something that could be caused by the time it takes your code to close the dialog and go back to the main form. You might look to see if there is anything else you are doing between the time the progress closes and you return UI control back to the user.
The system might simply be memory constrained and your operation causes a huge swap to disk. When the operation completes, windows might be notified that it needs to pull previously swapped memory from disk and shove it back into RAM, causing a delay.
I'd run the app with Nothing else loaded but task manager or resource monitor and see what happens. If the problem no longer occurs, then look into adding more RAM to your machine and/or ignore it.
If it's still occuring, and your memory usage leaves nearly nothing left then, again, add RAM or ignore.
If it's still occuring but memory usage is low, investigate your code to see what you are doing between the closing of the dialog and release of control of the main window back to the user.

You could try double buffering your form with this example:
Tends to eliminate flicker on screen updates.

Related

GMap.Net: Process takes a long time to close after window closes

I am testing out GMap.Net using WPF. So far I have only added the GMapControl, as well as setting some necessary stuff (CacheLocation, MapProvider, Zoom etc). The control is working well, except that when I close my window, it takes a while before VS recognizes that the debugging session has closed.
Apparently, my application's process is still running for some time before it terminates - it's not a bug in VS. This delay only appears when I do zoom/pan just before I close the window. I would want to guess something is still running, but I'm not sure how to tackle this problem.
Has anyone encountered this and have a solution?
What is happening is your program is still caching the tiles.
All you have to do is call gMap.Manager.CancelTileCaching(); when you exit your program or close the form.
gMap is what I named my instance of gMap.Net
Sounds like a there is a thread still running. I have noticed that the classes use the IDisposable interface. When you close the application/window, it is recommended that you call the .Dispose() method to clear any resources in use

WinForms MdiChildren Selection and Activation

I am a fairly experienced WinForms developer. I have an MdiApplication that used to work well. However, recently the main shell of the application, for which we use ComponentOne RibbonForm, has been updated in a big way. This update did affect some of our other 3rd party components, which we established was due to ComponentOne's use of DoEvents() in their event code. I thought I had cleaned up all of the code causing problems but I now have found another...
When I have multiple MdiChildren open and select one of these in code from an button click event on the ribbon form via
document.Activate();
document.EditorControl.Select();
document.EditorControl.Focus();
the other open MdiChildren documents still have focus, that it the forms are highlighted and input is not set on the document I set in code. Two questions:
How can I ensure that the Form I want to make active is the only one that is active?
Linking to the above; setting one form as active using form.Activate() should deactivate the others MdiChildren, but it is not - how can I deactivate the other windows in code?
Thanks for your time.
[Too long for a comment]
I am sick to the hind teeth with fighting C1. Esp. the Ribbon. I have confirmed with their support that they do use DoEvents() which they use to yield on their Gui threads. I am now going to switch to DevExpress which should be straight forward for my MVC application...
C1's use of DoEvents() messes up the normal flow of your application. DoEvents() is asynchronous which means it terminates before the application has actually processed any outstanding events, so if you're using it in a procedure with many sequential statements, calling DoEvents() causes a huge disturbance whenever it's called. This is what I think we are seeing when we perform our MDI operations, but we can never be sure without the C1 source code.
I hope this helps.

MonoMac window closing without error

I'm just starting out with MonoMac in Xamarin Studio, and I've run into the strangest problem:
I a window with an NSButton and a NSTextField on it. By this point I've cut out the event handler on the button, so it doesn't DO anything, except highlight when I click it. The button creation code looks like this:
nsButton = new NSButton(new System.Drawing.RectangleF(0, 0, 100, 100));
nsButton.BezelStyle = NSBezelStyle.RoundRect;
nsButton.Font = NSFont.SystemFontOfSize(
NSFont.SystemFontSizeForControlSize(NSControlSize.Regular));
nsButton.StringValue = text;
...and then it gets added to the window like so:
nsView.AddSubview(control.Handle as NSView);
(because in this part of the code, control.Handle is typed as object, and nsView is the main view on the window).
All runs and works fine at first. But, if I click repeatedly on that button, eventually the window just closes. No error, no exception, and the app itself doesn't quit; menus continue to respond and cheerfully log messages when I use them. But the window is simply -- gone.
It's extremely repeatable: it happens after 21 clicks. If I add an event handler that updates the NSTextField (e.g. hello.Caption="Foo";), then it happens after 19 clicks. It doesn't matter whether I click fast or slow; it's always the same number of clicks. Note that there is no code in the project to close the window, and the window doesn't even have a close box; I know of no legitimate way to close it short of quitting the app.
I am baffled here, and don't know how to debug this further. Does Xamarin have some sort of evaluation limit that closes your windows after so-many events? Is it a framework bug? Any insight will be greatly appreciated.
But, if I click repeatedly on that button, eventually the window just
closes. No error, no exception, and the app itself doesn't quit; menus
continue to respond and cheerfully log messages when I use them. But
the window is simply -- gone.
This "disappearing without a trace" sometimes occurs when an application crashes in native code badly enough. This can occur due to bugs in the binding code or mistakes made in calling the native APIs that corrupt internal cocoa state. I believe you are using MonoMac, and that this particular issue has been fixed in Xamarin.Mac.
You can sometimes get more information from the output window or by attaching lldb to your process.
This turned out to be the same issue as this one, in a slightly different guise.
In short, I wasn't keeping a reference to the NSWindow object, but instead was letting it go out of scope. So the GUI window would stick around for a while, but eventually (after some number of events or other code creating behind-the-scenes garbage) it is noticed and disposed of by the garbage collector. The window is then torn down.
It's all perfectly reasonable once you think of it, and happens under both Xamarin and MonoMac (just at slightly different times).
The simple solution, of course, is to retain a reference to the window until you're truly done with it. Problem solved!
(And yes, I feel a bit sheepish, but hopefully this question will get found by future Mac C# developers, and save them some grief.)

C# add-in for application (via COM) freezes when a Control is added to the form?

I am developing an extension for existing application via COM.
Current interface of the application to extend allows to create custom property windows and use them inside that application.
Now, I am using .NET for that purpose and have strange problems:
extensionForm = new Form();
extensionForm.SetBounds(0, 0, 100, 100);
extensionForm.Controls.Add(new Button());
ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");
As you can see below, the property sheets actually get extended, but after that something strange starts to happen.
Basically, if I switch to Ololo tab, then back to any of other 3 tabs (Attributes, Drawing or Services), the application freezes. I also know that the freeze happens inside of some unmanaged code block.
Another interesting fact here is that if I don't write the extensionForm.Controls.Add(new Button()) (with or without the Suspend / Resume Layout calls), everything works fine. So, if the recently constructed form has no controls (buttons or any other) on it, it doesn't freeze.
Here is a Spy++ log on the Ololo window right before the freeze (last message is the WM_CTLCOLORBTN, right after that the application became frozen):
Combining everything together:
Freezing happens only if I switch from Ololo to some other tab and then switch to the Ololo tab again.
Freezing only happens if the integrated form has at least one control on it, forms without controls don't freeze.
Application is not running any managed code at the moment and is not spending any CPU time.
So - any ideas / similiar problems solved / etc to help me in this case?
The Win32 HWND handles for the Forms in .NET are lazy initialized.
And I think this may be a problem here.
You may argue that the handle is created in your line ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo"); due to accessing Handle property.
It is true and what documentation acknowledges.
However, it creates the handle for the Form itself, but handles for child controls (Button in this case) are not created. This can be forced by calling CreateControl method. See more documentation.
I don't know if not having a handle for button may be a cause of your problem, but this is definitely something I would investigate.
To summarize, I suggest changing your code to:
extensionForm = new Form();
extensionForm.SetBounds(0, 0, 100, 100);
extensionForm.Controls.Add(new Button());
extensionForm.CreateControl();
ExApplAPI.AddCustomPropertyWindow(extensionForm.Handle.ToInt32(), "Ololo");
Are there any exception thrown?
We had an similar behavior when using WPF and COM, it solved by calling reset double calculation by using
[DllImport("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int _fpreset();
It is possible that the resource handle is not right. As you mentioned this happens only when the integrated form has atleast one control in it, Ololo tab is not able to find it's resources when active again. Please try storing resource handle the first time and then restoring it everytime the tab is active.
To understand why the application hangs, there are 2 things that may help:
Can you post a stack trace of the UI thread while the application is hung?
Which thread calls your code and actually creates the windows?

C# - Possible to safely have an owned form in a separate thread?

I am attempting to write a specialized onscreen keyboard (OSK) for an application I'm writing in C#. To facilitate this, I've created a form which has several buttons on it representing keys, and clicking them calls SendKeys and sends out the appropriate keys.
This form is owned by the main window that is shown when the application first starts, using the Owner property. This way, the OSK pops up whenever the user focuses the application, and it stays on top of the main window if it said main window is dragged over it.
This all works great, but because I have modal dialogs that I also want to use with the OSK, I attempted to create it in a separate thread, complete with its own message loop (via Application.Run) so it could still be usable with any modal dialogs in the main thread.
The problem with this is that, obviously, being in a separate thread can cause InvalidOperationExceptions because of cross-threaded calls. One specific example of this is when calling Application.Run(osk) from the new thread, a cross thread error occurs because it is attempting to update the window's handle with the owner (the main window).
My question is, is it possible to have an owned form on a thread that is separate from the owner in a safe manner? And, if failing that, is it possible to emulate an owned form's characteristics (namely being Always On Top for only the main window, and popping up when the main window is focused)?
Thanks, and sorry if this is confusing.
I think this is actually a bug in Windows Forms. Somewhat inevitable due to the way it checks for access to the Handle property by the wrong thread. The SDK docs for SetParent are not explicit about it, it states the requirement is that both windows belong to the same application. No mention of having to belong to the same thread. I know for a fact that the 'same application' requirement is not hard, there's appcompat code in Windows that makes this work for windows from different processes. Adobe Acrobat ab/used this for a long time. Which definitely absolves the 'same thread' requirement.
Well, punt the problem and try it out. Set Control.CheckForIllegalCrossThreadCalls to false before you set the owner, back to true afterward. And test the heck out of it. If you have trouble then try pinvoking SetParent() directly instead of setting the Owner. Windows Forms actually uses SetWindowLongPtr which is not recommended by the SDK.
I'll take a stab at this. Try running the OSK as a separate process.
Try using ShowDialog for the OSK as well instead of Application.Run - ShowDialog creates a message loop and ends it when the window is closed, and perhaps will solve your problems.
new Thread(() => new OSK().ShowDialog());
Why not use Control.Invoke to make cross-threaded calls to avoid InvalidOperationException?

Categories