不同调度员的WPF顶级窗口和子窗口?

时间:2011-07-11 10:39:02

标签: wpf dispatcher

好的,这就是我想要做的。我有一个令人讨厌的WPF控件(我被迫使用),它需要一个具有HWND的父级(因为它包含一些Windows.Forms的东西)并且有时可能非常无响应。这导致我的WPF应用程序也陷入困境并变得无法响应(响应速度会更准确)。我想将此控件移动到自己的Dispatcher上,以便在控件无响应时我的应用程序的Dispatcher不会被束缚。

我试图创建一个Window派生类来托管Control。我在STA线程上启动它并执行Dispatcher.Run()。到目前为止一切都很好。当我尝试将该Window派生类添加到我的应用程序中最顶层的Grid时,会发生这种不良。我得到“调用线程无法访问此对象,因为另一个线程拥有它。”异常。

我的应用程序的XAML:

<Window
x:Class="MyAppWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid
    ClipToBounds="True"
    x:Name="mainGrid"
    Grid.Row="1">
</Grid>
</Window>

myApp.cs

public class MyAppWindow :Window
{
    CrapControlWindow crapControlWindow;
    Dispatcher crapControlWindowDispatcher;
    Dispatcher myAppDispatcher;

    public MyAppWindow()
    {
        myAppDispatcher = Dispatcher.CurrentDispatcher;
        Thread launchThread = new Thread(new ThreadStart(crapControlHostLauncher));
        launchThread.IsBackground = true;
        launchThread.ApartmentState = ApartmentState.STA;
        launchThread.Start();
    }

    public Initialize()
    {
        mainGrid.Children.Add(crapControlWindow); <--- Fails Here
    }

    void crapControlHostLauncher()
    {
        crapControlWindowDispatcher = Dispatcher.CurrentDispatcher;
        Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
        {
            crapControlWindow = new crapControlWindow();
        });
        Dispatcher.Run();
    }
}

子窗口的XAML:

<Window x:Class="CrapControlWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Crappy Control Window" Height="300" Width="300">
    <Grid x:Name="mainGrid">
        <CrapControl
            Grid.Row="1"
            Name="crapControl1"
            ClipToBounds="True"
            Margin="0,4,0,4" />
    </Grid>
</Window>

我尝试了失败行的各种排列 - crapControlWindowDispatcher.Invoke,myAppDispatcher.Invoke等NADA!同样的例外......

所以把它放在我身上 - 我疯了吗?其他策略?我可以做这个工作吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您继承自Window但正在尝试在Window内托管Grid。由于Dispatcher是顶级元素,因此它是否具有相同Window无关紧要。您可以拥有单独的窗口,每个窗口都有自己的Dispatcher,但它们需要显示为单独的窗口。我知道无法将控件与自己的Dispatcher集成到另一个具有不同Dispatcher的WPF控件中。

有关单独窗口的示例,每个窗口都有自己的调度程序see here