0

I am trying to use a FolderBrowserDialog as it was mentioned here:

var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();

If I call the Dialog when a button is pressed, it works just fine. But I want to open the Dialog in the middle of my code (there is an incoming file through a socket, so between receiving it and saving it I try to get the path to save it to), and it simply won't happen.

Here is the part of the code where it is called:

 byte[] clientData = new byte[1024 * 5000];
 int receivedBytesLen = clientSocket.Receive(clientData);

 var dialog = new System.Windows.Forms.FolderBrowserDialog();
 System.Windows.Forms.DialogResult result = dialog.ShowDialog();
 string filePath = dialog.SelectedPath;

 int fileNameLen = BitConverter.ToInt32(clientData, 0);
 string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
 BinaryWriter bWrite = new BinaryWriter(File.Open(filePath + "/" + fileName, FileMode.Append)); ;
 bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
 bWrite.Close();

How should I try to open the Dialog for it to work?

Community
  • 1
  • 1
lacer
  • 81
  • 10
  • There isn't enough information here. `in the middle of my code` Does the code run on your WPF project or in a shared library? Is it running on the UI thread? Do you get any exceptions? Also, post the section of the code where it fails. What you've provided is very generic. – Arian Motamedi Dec 05 '14 at 19:44
  • @PoweredByOrange added the code. It runs on the WPF project, and it runs on the UI thread. No exceptions. – lacer Dec 05 '14 at 19:49
  • Thank you, that's better. Have you tried setting a breakpoint to see if it actually gets hit? – Arian Motamedi Dec 05 '14 at 19:51
  • @PoweredByOrange Yes, it most definitely gets hit. And I missed it before, but there is actually an `System.Windows.Threading.ThreadStateException` thrown. `Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it.` – lacer Dec 05 '14 at 19:56
  • Can you post the code where it receives the file over a socket? – Michael Adamission Dec 05 '14 at 19:56
  • You are trying to show an UI object in a non UI thread. Show your entire method my guess is it is an EventHandler that is being run in another thread – Mark Hall Dec 05 '14 at 20:02
  • How did you make sure that this code is running in the ui thread? Did you check the return value of Dispatcher.CheckAccess (WPF) or Control.InvokeRequired (WinForms). Is your ui thread STA? – bernd_rausch Dec 05 '14 at 21:26

2 Answers2

2

As others stated you are most likely in a separate thread when trying to call a UI dialog.

In the code you posted you can use the WPF method BeginInvoke with a new Action that will force the FolderBrowserDialog to be invoked in a UI thread.

        System.Windows.Forms.DialogResult result = new DialogResult();
        string filePath = string.Empty;
        var invoking = Application.Current.Dispatcher.BeginInvoke(new Action(() =>
        {
            var dialog = new System.Windows.Forms.FolderBrowserDialog();
            result = dialog.ShowDialog();
            filePath = dialog.SelectedPath;
        }));

        invoking.Wait();

If you are creating a separate thread you can set the ApartmentState to STA and this will allow you to call UI dialogs without having to invoke.

        Thread testThread = new Thread(method);
        testThread.SetApartmentState(ApartmentState.STA);
        testThread.Start();
Seritin
  • 36
  • 4
0

Because you're getting the STA exception, it means you are probably running on a background thread.

InvokeRequired/BeginInvoke pattern to call the dialog:

if (InvokeRequired)
{
        // We're not in the UI thread, so we need to call BeginInvoke
        BeginInvoke(new MethodInvoker(ShowDialog)); // where ShowDialog is your method

}

see: http://www.yoda.arachsys.com/csharp/threads/winforms.shtml. see: Single thread apartment issue

Community
  • 1
  • 1
  • I won't deny that I am somewhat clueless in this area, but [this](http://pastebin.com/7c60KaM0) is what I tried (I had no idea how to make your example work). But it is obviously not working. So, could you elaborate? – lacer Dec 05 '14 at 20:47