OpenFileDialog began hanging when called directly from some of my code. (I'm dealing with C# 2.0 here.)
Turns out it doesn't run in it's own thread, but takes over your main thread. Vista just isn't a big fan of this. To get around it you need to invoke OpenFileDialog from within another thread. I stumbled upon this code that will work nice any time you need to popup another dialog window (such as a process indicator or built in ones like OpenFileDialog). Hopefully our pals over in Redmond fix up OpenFileDialog to just do this by default in the future.
I stumbled upon this code out in the blogosphere (https://forums.microsoft.com) awhile ago.
public class Invoker
{
public OpenFileDialog InvokeDialog;
private Thread InvokeThread;
private DialogResult InvokeResult;
public Invoker()
{
InvokeDialog = new OpenFileDialog();
InvokeThread = new Thread(new ThreadStart(InvokeMethod));
InvokeThread.SetApartmentState(ApartmentState.STA);
InvokeResult = DialogResult.None;
}
public DialogResult Invoke()
{
InvokeThread.Start();
InvokeThread.Join();
return InvokeResult;
}
private void InvokeMethod()
{
InvokeResult = InvokeDialog.ShowDialog();
}
}
Usage :
Invoker I = new Invoker();
if (I.Invoke() == DialogResult.OK)
{
MessageBox.Show(I.InvokeDialog.FileName, "Test Successful.");
}
else
{
MessageBox.Show("Test Failed.");
}
Sunday, November 9, 2008
OpenFileDialog.showDialog hangs on Vista
Posted by Socratic Cyborg at 3:58 PM
Subscribe to:
Post Comments (Atom)
5 comments:
Thank you, thank you, thank you! I ran into this and kept thinking the problem was that the UI thread was what needed to be doing the showDialog(). Many of hours wasted racking my brain, and this works perfectly. Thanks again.
Thanks a lot for this example! Works great! You saved my time and energy! Thanks again!
Thanks a lot, you saved my poor programmers life ;o)
Thanks. Truly we are not worthy
Or, simpler:
private static DialogResult InvokeFileDialog( FileDialog dialog )
{
DialogResult result = DialogResult.None;
Thread t = new Thread(
new ThreadStart(
delegate
{
result = dialog.ShowDialog();
} ) );
t.SetApartmentState( ApartmentState.STA );
t.Start();
t.Join();
return result;
}
Post a Comment