将主窗口设置为从STA线程调用的对话框所有者(消息框)

时间:2013-12-15 12:21:53

标签: c# wpf multithreading

这是一个调用自定义C#消息框的函数。该函数是从一个在非线程的线程内运行的模拟进程调用的。

public Output.ButtonResult msgboxYesNo(string Text, string title) {
    Output.Message_Box msg = new Output.Message_Box();

    msg.Dispatcher.Invoke(new Action(() => {
        msg.seeQuestion(Text, title);
        msg.Topmost = true;
        Application.Current.MainWindow.Dispatcher.Invoke(new Action(()
                          => { msg.Owner = Application.Current.MainWindow; }));
        msg.ShowDialog();                
    }));

    return msg.result;
}

问题在于这一行:

Application.Current.MainWindow.Dispatcher.Invoke(new Action(() =>
                              { msg.Owner = Application.Current.MainWindow; }));

它抛出了这个:

  

调用线程无法访问此对象,因为它不同   线程拥有它

因为我想将主窗口设置为自定义消息框的所有者,该消息框在一个单独的线程中调用。

如何将主窗体设置为消息框的所有者?

(我希望我能够清楚地解释这个问题,表格是WPF)

1 个答案:

答案 0 :(得分:1)

Output.Message_Box是一个UI组件,因此它应该只从UI线程创建,而不是从后台线程创建。

代码中的问题 -

msgcreated on background thread,但您正在尝试access it from UI thread此处

msg.Owner = Application.Current.MainWindow;

相反,你甚至应该create message box on UI thread only

Application.Current.Dispatcher.Invoke(new Action(() =>
{
    Output.Message_Box msg = new Output.Message_Box();
    msg.seeQuestion(Text, title);
    msg.Topmost = true;
    msg.Owner = Application.Current.MainWindow;
    msg.ShowDialog(); 

    return msg.result;               
}));

此外,您正尝试从在UI线程上创建的后台线程访问MainWindow。 如果应用程序仅从主线程启动,您可以获得这样的UI调度程序:Application.Current.Dispatcher