lacer
lacer

Reputation: 81

C# How to open a FolderBrowserDialog in the middle of the code?

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?

Upvotes: 0

Views: 2564

Answers (2)

Seritin
Seritin

Reputation: 36

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();

Upvotes: 2

Michael Adamission
Michael Adamission

Reputation: 493

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

Upvotes: 0

Related Questions