【问题标题】:Dispatcher.BeginInvoke to call another window in c#Dispatcher.BeginInvoke 在 C# 中调用另一个窗口
【发布时间】:2013-03-18 17:40:38
【问题描述】:

在我的 wpf 应用程序中,我将按钮单击事件作为单独的线程并作为后台进程运行,以便 UI 响应用户。代码如下,

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
   //Makes the conversion process as background task which 
   //makes the UI responsive to the user.
   Thread thread = new Thread(new ThreadStart(WorkerMethod));
   thread.SetApartmentState(ApartmentState.MTA);
   thread.IsBackground = true;
   thread.Start();
}

在 WorkerMethod 中,我可以选择更改为用户提供单独窗口的文件名。对于此操作,我使用如下 Dispatcher 方法,

if (MessageBox.Show("Do you want to set filename?", 
    "Information", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == 
    MessageBoxResult.Yes)
{                         
    Action showOutput = () =>
    { 
        BlueBeamConversion.SetOutput _setOutput = 
            new BlueBeamConversion.SetOutput(); 
        _setOutput.ShowDialog();
    }; 

    Dispatcher.BeginInvoke(showOutput);

    if (String.IsNullOrEmpty(MainWindow.destinationFileName))
              return;

destinationFileName 将在 SetOutput 窗口中设置。现在来谈谈我的问题,当上面的代码执行时,SetOutput 窗口会出现并且不会等到我设置文件名。在设置文件名之前,它涉及到下面的代码,

if (String.IsNullOrEmpty(MainWindow.destinationFileName))
                                return;

我怎么能坚持到我点击 setoutput 窗口中的确定按钮。欢迎提出任何建议。

我使用了 dispatcher.Invoke 而不是 BeginInvoke。现在它持有窗口并采用新名称。但是当在某一行继续工作方法中的代码时,它会退出应用程序本身,请对代码进行罚款,

if (MessageBox.Show("Do you want to set filename?", "Information", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
                    {

                        Action showOutput = () =>
                        { BlueBeamConversion.SetOutput _setOutput = new BlueBeamConversion.SetOutput();  _setOutput.ShowDialog(); }; 
                       Dispatcher.Invoke(showOutput);

                    for (int i = 0; i < _listFiles.Items.Count; i++)--- here it exits
                {--------- }

问候 桑吉塔

【问题讨论】:

  • 什么是_listFiles?另外:请尝试格式化以提高可读性。
  • _listFiles 是名称列表视图控件。浏览文件并将其添加到列表视图。
  • 从发布的代码中我想说:根本不要使用线程。

标签: c# wpf


【解决方案1】:

使用 ShowDialog() 代替 Show() 并将输出存储在 DialogResult 中

 var result = _setOutput.ShowDialog();

【讨论】:

    【解决方案2】:

    您可以使用 Invoke 代替 BeginInvoke :

     //Dispatcher.BeginInvoke(showOutput);
     Dispatcher.Invoke(showOutput);
    

    【讨论】:

    • 我认为 OP 必须结合答案。
    • Dispatcher.Invoke(showOutput);拿着窗户。但现在我面临另一个问题。在 setoutput 窗口中给出文件名后,然后按确定,工作方法代码将继续。但是当它到达 (int i = 0; i
    • if (MessageBox.Show("你想设置文件名吗?", "信息", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { Action showOutput = () => { BlueBeamConversion.SetOutput _setOutput = new BlueBeamConversion.SetOutput(); _setOutput.ShowDialog(); }; Dispatcher.Invoke(showOutput); for (int i = 0; i
    【解决方案3】:

    如果您使用 ShowDialog,您可以将值存储在第二个窗口的公共属性中,并可以通过以下方式访问它:

    Form2 form2 = new Form2();
    if (form2.ShowDialog() == DialogResult.OK)
    {
    if (form2.ReturnData == "myResult")
    

    ... }

    【讨论】:

      【解决方案4】:

      当您在操作中使用 window.show() 方法时,您不会从 show 方法收到任何结果,您必须调用 window 的 show dialog 方法,这将强制 GUI 保持直到对话框窗口关闭并且之后,您将能够从对话框窗口中接收数据。

       Action showOutput = () =>
                                  { BlueBeamConversion.SetOutput _setOutput = new BlueBeamConversion.SetOutput(); _setOutput.ShowDialog(); }; 
                              Dispatcher.BeginInvoke(showOutput);
      

      另一方面,您可以先等待线程完成,然后再等待。这种方法也适用于您。 dispatcher.Invoke 会帮助你。或者你可以在这里尝试 DispatcherOperation。

      尝试使用以下更改的代码。

        DispatcherOperation op = Dispatcher.BeginInvoke(showOutput);
      
                      op.Wait();
      
                      if (String.IsNullOrEmpty(output))
                          return;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-20
        • 1970-01-01
        • 2011-10-01
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多