Why is Dialogresult nil? - winforms

This never happened to me before.
I do have System.Windows.Forms namespace under uses clause and I am able to use DialogResult's properties. Look at the code below. It's where the problem is in my program.
if (thewinform.ShowDialog=DialogResult.OK) then
I did debug it and dialog winform opens. Once I click the OK button and returns to check on the DialogResult, it skips the if block of code. At which point, I noticed that DialogResult is actually NIL
I never encountered anything like this before.
Any ideas? Thanks,

I found the answer to my question.
When you want to use a winform purely as a dialog box, then you CANNOT have FormClosing event.
For my thewinform, I accidently created its FormClosing event and forgot about it.
method thewinform.thewinform_FormClosing(sender: System.Object; e: System.Windows.Forms.FormClosingEventArgs);
begin
e.Cancel := true;
hide;
end;
Once I removed this winform event, ShowDialog and DialogResult is behaving as expected.
This is very similar to another stackoverflow question Why does ShowDialog always return DialogResult.Cancel?

Related

Closing messagebox from modal dialog closes the dialog

I have a custom modal dialog from which I want to invoke a Messagebox on error.
However on closing the messagebox, the dialog also closes.
Is there a way to keep the dialog open and just close the messagebox?
This seems to be the same issue as the one mentioned here. I found a way to fix it and through it, probably proof that it is indeed a bug. My solution, as mentioned here:
A workaround on this is to add a handler for the FormClosing event of your form, so you can cancel it there.
It seems that the bug is somewhat detectable by checking FormClosingEventArgs.CloseReason. This is normally "UserClosing" on normal close (even programmatically with calling this.Close()), but with this bug it's set to "None", a value I would assume is some kind of default that should normally never be used.
private void form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.None)
{
e.Cancel = true;
return;
}
// any other OnClose code you may wish to execute.
}
[EDIT]
Sorry, the issue in the linked question was OP using form.DialogResult as temp variable for the result of a message box, and that caused the main form to close, so that is, in fact, not related. Use a temp variable for stuff like that, folks.
The most likely real cause of this is that the form's AcceptButton is set, and the actual accept button's code does validation. Even if the validation raises an error, AcceptButton will cause the form's DialogResult to be set to OK, which closes the form. To prevent this, either don't set the AcceptButton property and just set the DialogResult manually, or, on error, specifically clear the DialogResult by setting it to DialogResult.None.

Form closing immediately

Dim details As New frmDetails(ID, JobID, True)
details.ShowDialog()
The form flashes open and immediately closes. If I use Show() rather than ShowDialog() it stays open and look fine. Here are some things I've checked:
Breaking in FormClosing shows only
System.Windows.Forms.Form.OnFormClosing
System.Windows.Forms.Form.CheckCloseDialog
System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FContinueMessageLoop
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner
System.Windows.Forms.Application.ThreadContext.RunMessageLoop
System.Windows.Forms.Application.RunDialog
System.Windows.Forms.Form.ShowDialog
between the ShowDialog and the FormClosing.
CloseReason is "None"
Load runs to the end, as does VisibleChanged (though Activated never gets called).
There's no sign of any Exceptions being thrown.
Intellitrace doesn't show anything going on.
After the form closes, the DialogResult is "Cancel" (There's no reference to DialogResult in the form or its Designer)
I'm not doing any explicit threading
I'd appreciate any suggestions either as to what's going on or how to go about finding out.
Thanks.
In my case I was setting the DialogResult property on the load event to Cancel, and that was causing the dialog to close immediately after Load. I've set it to the default None and now I only set it to other value on the Click event of a button when I really need to close it.
Well, this will probably do nobody any good, but here's how I solved the problem:
There was a line in the Load method that read
Me.Text = ""
I have no idea what it was doing there (this isn't my code, thank goodness), especially since the value gets set again later on, but taking that line out stopped the form from mysteriously closing. Go figure.
I had a similar problem. In my case it was due to not specifying the parent window on the ShowDialog(). The dialog associated with the window that was topmost, which happened to be a combobox drop-down that was going away.
In my case, I changed the ShowDialog() call to use my application's main window as the parent, and problem solved.
Been debugging for couple of hours with the same problem. In my case the likely reason was that the parent form has setting ShowInTaskbar = false in Load event, while my form had this set to true in the designer. For some reason this caused the dialog result to be set to Cancel during initialization.

The whole wpf application is blocked after i call Show() for new window

I am developing a WPF-application using mvvm pattern. And a strange problem occurred to me.
There is a form, which contains a devexpress DXGrid control. There is a command binded to double click gesture in presenter. When the command triggers a new window is created and shown through factory class(the Show() method is used).
So, it happens from time to time that the whole application(all application windows) is blocked when this window is shown. This lockup disappears after i focus any other application.
For the first time this problem occurred after updating devexpress version. Then this problem occurred any time new window was shown after double click on grid row. The problem was partially fixed by setting new window`s Owner property.
Now this problem occurs from time to time. It seems as if threads are involved here, but i dont understand how. =(
p.s.:
there is one more strange thing, when new window is shown and no lockup-problem occurred, the first window is still focused and i have to click on newly shown window before i can use any controls, placed on it.
I have tried:
set ShowActivated property
call Activate() after Show()
newform.Dispatcher.CheckAccess() to
determine which thread calls Show()
method
check newform.IsActive property after
show (value = true)
Could you tell me how to fix, please?
Thank you.
Well to fix the issue of first window being focused rather than the newly shown window, you need to do the following, after calling the show method for the new window:
Mouse.Capture(null);
Hopefully the issue would be resolved.

Setting DialogResult only after ShowDialog() in WPF

I have a window that I sometimes open using Show() and sometimes using ShowDialog(). In the second case, the returned dialog result is important for me. But if I set the DialogResult after calling Show() I get an InvalidOperationException. Is there a way to find out which method was used to open the window and set or not the DialogResult accordingly? Or is there another way?
Of course I know I can catch and ignore the exception, but I don't like this solution.
Use System.Windows.Interop.ComponentDispatcher.IsThreadModal inside the window to determine if it runs on a modal thread or not.
If you look at set_DialogResult in Reflector, it checks _showingAsDialog to determine whether the dialog is modal. Unfortunately this is a private field.
Do you always construct a new instance of the window before calling Show()/ShowDialog(). If so, you could pass an argument to the constructor indicating how it is to be shown.
You can use the Form.Modal property to check the kind of usage.
In the case of using Form.Show() you have to use another way to let the caller know of any results of the Form.
Is there a reason to use both ways of showing the form?
How about just setting this.DialogResult = DialogResult.blah in the form closing event?

how to set wpf MessageBox.Owner to desktop window because SplashScreen closes MessageBox

I am using the SplashScreen feature in WPF by setting a bitmap's Build Action to Splashscreen. Behind the splash screen, licensing information is being check, and if it fails I show a MessageBox.
According to this Feedback, it is because the MessageBox.Owner is the splash screen and as soon as another window is open even if it is a MessageBox the splash screen window is closed which then in turn closes the MessageBox, so the user never sees the MessageBox.
So the workaround would be to set the MessageBox.Owner to another window, but that would mean that I have to instantiate another window which might not even be needed.
Would it be possible to set the MessageBox.Owner to the desktop window? And how, because the only other function that comes to mind is the GetDesktopWindow() api function, but that returns a window handle and MessageBox.Owner is a WPF Window.
Since using the desktop window as the parent for your modal dialogs is not a good idea, as #Nir pointed out in his answer, here are three other workarounds:
1) Use a hidden window. Create a tiny, non-modal window to act as the parent for your MessageBox or other modal dialog. This approach is described here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/116bcd83-93bf-42f3-9bfe-da9e7de37546/
2) Create non-modal message windows. Change your startup mode to explicit shutdown and use a non-modal window to display your message. This approach is described in the answer to this StackOverflow question:
MessageBox with exception details immediately disappears if use splash screen in WPF 4.0
3) Call MessageBox twice. Apparently, the problem only affects the first modal dialog shown. So you could simply call your modal dialog twice, if you didn't mind the flash of the first one opening and closing.
https://connect.microsoft.com/VisualStudio/feedback/details/600197/wpf-splash-screen-dismisses-dialog-box
Personally, I don't like any of these workarounds. The only other option is to avoid the built-in SplashScreen functionality and to roll your own from scratch. Here's a link if you want to investigate that route further:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8dd49fd0-9cc9-43c6-b285-6f119ab8a32e/
Finally, if you're as annoyed by this issue as I am, you can vote for Microsoft to fix this bug here:
http://connect.microsoft.com/VisualStudio/feedback/details/600197/wpf-splash-screen-dismisses-dialog-box
I came up with this solution myself, so maybe there's something wrong with it, but it seems to work perfectly:
Window temp = new Window() { Visibility=Visibility.Hidden };
temp.Show();
MessageBox.Show(temp, "An error occurred before the application could start.\n\nTechnical Details: " + ex.Message, "Fatal Error", MessageBoxButton.OK, MessageBoxImage.Stop);
App.Current.Shutdown(1);
I found the problem. I am also using the build-in splash screen which causes this: WPF SplashScreen closes MessageBox
Can you post some code? I just tried adding this to the App.xaml.cs file in a new WPF application:
protected override void OnStartup(StartupEventArgs e)
{
if (MessageBox.Show("Start app?", "Confirm Start",
MessageBoxButton.YesNo) == MessageBoxResult.No)
{
this.Shutdown();
return;
}
this.StartupUri = new Uri("Window1.xaml", UriKind.Relative);
base.OnStartup(e);
}
... and it works as expected (the "Confirm Start" prompt stays open until I've responded, and if I click "No" the app shuts down).
The desktop window is never the correct parent, read this to know why:
http://blogs.msdn.com/oldnewthing/archive/2004/02/24/79212.aspx
Now the problem described in this post doesn't happen so much because MS worked around it, in this post you can see how:
http://blogs.msdn.com/oldnewthing/archive/2006/11/02/931674.aspx
This issue is still an issue, I faced it recently. For me, the solution was to close immediately the splash screen in case of any issues:
SplashScreen splash = new(Assembly.GetAssembly(typeof(GuiApp))!, "Resources/img_my.png");
splash.Show(false);
using ServiceProvider? services = initializeApp();
if (services == null)
{
splash.Close(TimeSpan.Zero);
return -3;
}
After that MessageBox displayed normally.
this has helped me a lot .....
Given me new idea
but the example code that i have seen here has some modification required
here is an simple example in wpf with modification
now it is working
on button click
paste this code
if (System.Windows.Forms.MessageBox.Show("are u sure", "delete", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
{
this.Close();
}
else
{
MessageBox.Show("why not to delete");
}
This is not directly related to the OP's situation, but might be useful for others who are having problems with MessageBox being hidden behind other windows in certain special situations.
As #dthrasher mentions, one solution is to use a hidden dummy window. But sometimes even that is not enough. I had a situation where the solution was to not only use a hidden dummy window, but to turn on its TopMost property whenever I used it with MessageBox.
_formKludge.TopMost = true;
MessageBox.Show(_formKludge, "Nice informative message.", "Super-duper Program",
MessageBoxButtons.OK, MessageBoxIcon.Error);
_formKludge.TopMost = false;

Resources