【问题标题】:How to open file browser dialog in a dynamically created form?如何以动态创建的形式打开文件浏览器对话框?
【发布时间】:2013-11-25 09:53:29
【问题描述】:

我的应用程序中有两种形式,一种是在设计时生成的,另一种是在运行时动态生成的。在运行时生成的表单中有一个上下文菜单,其中有一个打开FolderBrowserDialog 的项目。每当我尝试单击该项目时,就会出现错误提示

  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. This exception is only raised if a debugger is attached to the  

  process.

如在其他问题中所解释的,上述问题的解决方案是将Main() 方法标记为[STA Thread],但在我的情况下已经存在。那么,我该如何解决这个问题呢?
我调用对话框的方式是:-

    private void RightClickMenuClicked(object sender, ToolStripItemClickedEventArgs e)
    {
       if (e.ClickedItem.ToString() == "Copy")
        {
           FolderBrowsing.ShowDialog() ; 
           // Do other stuff here ....
        }
   }

【问题讨论】:

  • 你能贴一些代码说明你是怎么做到的吗?
  • @Szymon 我已经发布了一些代码。

标签: c# .net multithreading user-interface sta


【解决方案1】:

在 Windows 窗体或 WPF 中,用户界面只能在单线程中运行。您必须使用Invoke 方法将您的附加窗口调用到Dispatcher 中——这将强制UI 线程处理它。 (Kyle的做法有点类似)

【讨论】:

    【解决方案2】:

    我不知道你是如何调用 ShowDialog 方法的。你可以试试下面的代码

        private DialogResult STAShowDialog(FolderBrowserDialog dialog)
        {
            DialogState state = new DialogState();
            state.dialog = dialog;
            System.Threading.Thread t = new  
                   System.Threading.Thread(state.ThreadProcShowDialog);
            t.SetApartmentState(System.Threading.ApartmentState.STA);
            t.Start();
            t.Join();
            return state.result;
        }
    
        public class DialogState
        {
          public DialogResult result;
          public FolderBrowserDialog dialog;
    
    
          public void ThreadProcShowDialog()
          {
            result = dialog.ShowDialog();
          }
        }
    

    然后在你的按钮点击或其他地方你可以尝试

         private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog _myfolderDialog= new FolderBrowserDialog();
            frm.InitializeLifetimeService();
    
    
            DialogResult _result= STAShowDialog(_myfolderDialog);
            if (result== DialogResult.OK)
            {
                //Do your stuff
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 2021-11-02
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      相关资源
      最近更新 更多