【问题标题】:C# How to open a FolderBrowserDialog in the middle of the code?C#如何在代码中间打开一个FolderBrowserDialog?
【发布时间】:2015-02-04 01:39:48
【问题描述】:

我正在尝试使用提到的 FolderBrowserDialog here:

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

如果我在按下按钮时调用对话框,它就可以正常工作。但是我想在我的代码中间打开对话框(有一个通过套接字传入的文件,所以在接收它和保存它之间我尝试获取保存它的路径),它根本不会发生。

这是调用它的代码部分:

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

我应该如何尝试打开对话框以使其工作?

【问题讨论】:

  • 这里没有足够的信息。 in the middle of my code 代码是在您的 WPF 项目上运行还是在共享库中运行?它是否在 UI 线程上运行?你有任何例外吗?另外,发布失败的代码部分。您提供的内容非常笼统。
  • @PoweredByOrange 添加了代码。它在 WPF 项目上运行,并且在 UI 线程上运行。没有例外。
  • 谢谢,这样更好。您是否尝试过设置断点以查看它是否真的被命中?
  • @PoweredByOrange 是的,它肯定会受到打击。我之前错过了,但实际上抛出了一个System.Windows.Threading.ThreadStateExceptionCurrent 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.
  • 你能把代码贴在它通过套接字接收文件的地方吗?

标签: c# .net wpf folderbrowserdialog


【解决方案1】:

正如其他人所说,当您尝试调用 UI 对话框时,您很可能处于单独的线程中。

在您发布的代码中,您可以将 WPF 方法 BeginInvoke 与新的 Action 结合使用,这将强制在 UI 线程中调用 FolderBrowserDialog。

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

如果您正在创建一个单独的线程,您可以将 ApartmentState 设置为 STA,这将允许您调用 UI 对话框而无需调用。

        Thread testThread = new Thread(method);
        testThread.SetApartmentState(ApartmentState.STA);
        testThread.Start();

【讨论】:

    【解决方案2】:

    因为您收到 STA 异常,这意味着您可能正在后台线程上运行。

    InvokeRequired/BeginInvoke 模式调用对话框:

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

    请参阅:http://www.yoda.arachsys.com/csharp/threads/winforms.shtml。 见:Single thread apartment issue

    【讨论】:

    • 我不会否认我在这方面有些无能为力,但this 是我尝试过的(我不知道如何使您的示例工作)。但这显然行不通。那么,您能详细说明一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    相关资源
    最近更新 更多