【问题标题】:How can I show dialog on UI thread from another如何在另一个 UI 线程上显示对话框
【发布时间】:2014-10-28 09:37:38
【问题描述】:

我在多个线程上使用 Show.Dialog,但是有一个问题。 当从 UI 线程调用的对话框关闭时, 即使仍有一些从另一个线程调用的对话框,也会激活 MainWindow。 为了避免这种情况,我想在另一个 UI 线程上显示对话框,但这怎么可能呢? 或者有没有其他方法可以避免这个问题?

public partial class CustomMsgBox : Window
{
    //this class implements a method that automatically
    //closes the window of CustomMsgBox after the designated time collapsed

    public CustomMsgBox(string message)
    {
        InitializeComponent();
        Owner = Application.Current.MainWindow;
        //several necessary operations...
    }

    public static void Show(string message)
    {
        var customMsgBox = new CustomMsgBox(message);
        customMsgBox.ShowDialog();
    }
}

public class MessageDisplay
{
    //on UI thread
    public delegate void MsgEventHandler(string message);
    private event MsgEventHandler MsgEvent = message => CustomMsgBox.Show(message);

    private void showMsg()
    {
        string message = "some message"
        Dispatcher.Invoke(MsgEvent, new object[] { message });
    }
}

public class ErrorMonitor
{
    //on another thread (monitoring errors)
    public delegate void ErrorEventHandler(string error);
    private event ErrorEventHandler ErrorEvent = error => CustomMsgBox.Show(error);
    private List<string> _errorsList = new List<string>();

    private void showErrorMsg()
    {
        foreach (var error in _errorsList)
        {
            Application.Current.Dispatcher.BeginInvoke(ErrorEvent, new object[] { error });
        }
    }
}

当从UI线程调用的CustomMsgBox自动关闭时, 即使仍然有一些从监视线程调用的 CustomMsgBoxes,MainWindow 也会被激活。

【问题讨论】:

    标签: c# wpf multithreading dialog


    【解决方案1】:

    您应该只从 UI 线程打开对话框。您可以使用调度程序调用 UI-Thread:

    // call this instead of showing the dialog direct int the thread
    this.Dispatcher.Invoke((Action)delegate()
    {
        // Here you can show your dialiog
    });
    

    您可以简单地编写自己的ShowDialog / Show 方法,然后调用调度程序。

    我希望我理解你的问题是正确的。

    【讨论】:

    • 我很抱歉我第一次给出的信息不足,但是两个方法 showMsg() 和 showErrorMsg() 存在于不同的类中。如何在 ErrorMonitor 类中获取我的 MainWindow,其中错误监视方法在不同的线程中定期执行。当我尝试 Application.Current.MainWindow.Dispatcher.BeginInvoke 时,出现异常消息“调用线程无法访问此对象,因为不同的线程拥有它”。
    • 感谢您的回复。但我收到一条错误消息“无法解析符号'Dispatcher'”。
    • 我让我的 ErrorMonitor 类继承了 Window,并且 this.Dispatcher.BeginInvoke 正常工作。但是,当从 MessageDisplay 类调用的对话框关闭时,即使仍有一些从 ErrorMonitor 类调用的对话框,也会激活 MainWindow。我不希望它被激活。
    • 如果您使用 Topmost: msdn.microsoft.com/de-de/library/… 会怎样?
    • 我将 MainWindow 的最顶层设置为 false,但它并没有引起任何变化。当有任何对话框时,MainWindow中的所有控件都应该是不可选择的。
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    相关资源
    最近更新 更多