2

我正在像这样的新线程中打开新的 WPF 窗口:

private void OnCreateNewWindow(object sender, RoutedEventArgs e)
{
    Thread thread = new Thread(() =>
    {
        Window1 w = new Window1();
        w.Show();
        Dispatcher.Run(); 
    });

    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    }
}

问题是它卡在 Show-method 上(不显示窗口)并且永远不会到达 Dispatcher.Run。

检查线程和调用堆栈时,我可以看到两个线程,Main 和我的新窗口线程。窗口线程的调用堆栈位于以下帧:

PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(object sender, System.Windows.RoutedEventArgs e, System.Windows.Input.ICommand command, bool execute) + 0x1c0 bytes

在尝试修改代码时,我曾经设法得到消息异常:

不能使用属于与其父 Freezable 不同的线程的 DependencyObject。

我感觉这与访问未被冻结的主线程拥有的资源有关。在这个应用程序中,我有很多通用样式和资源、画笔等,但我试图通过将以下内容放在窗口的构造函数中来避免在这个特定对话框中使用它们:

InheritanceBehavior = InheritanceBehavior.SkipAllNow;

但这似乎还不够。不知何故,似乎无论如何都访问了一些不允许的资源。

带有 FindCommandBinding 的框架暗示它可能是命令绑定的问题。但是这个对话框没有命令绑定。

如果在资源字典中定义了诸如画笔之类的资源,它们是否会被隐式冻结?如果没有,我如何以简单的方式明确冻结它们?有数百个刷子。但这可能不是这里的问题。

还有其他想法吗?

4

1 回答 1

-2

您需要使用 Dispatcher.Invoke 或 BegingInvoke 方法来执行 winodw 对象的创建和调用 show 方法。工作线程不能调用或更新控件。

Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, () => new Thread(() =>     { Window1 w = new Window1();         w.Show();})
于 2012-08-28T08:09:16.357 回答