将在后台线程中创建的wpf按钮添加到Mainwindow

时间:2012-06-06 06:58:46

标签: wpf multithreading

这是我的场景:我有一个带按钮的简单wpf窗口。当用户点击按钮时,我想创建另一个窗口(让我们称之为子窗口),然后在后台线程上创建一个wpf按钮,将其添加到子窗口并显示子窗口。这是代码:

        Button backgroundButton = null;
        var manualResetEvents = new ManualResetEvent[1];
        var childWindow = new ChildWindow();
        manualResetEvents[0] = new ManualResetEvent(false);
        var t = new Thread(x =>
        {
            backgroundButton = new Button { Content = "Child Button" };
            childWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => childWindow.MainPanel.Children.Add(backgroundButton)));
            manualResetEvents[0].Set();
        });
        t.SetApartmentState(ApartmentState.STA);
        t.Start();

        WaitHandle.WaitAll(manualResetEvents);
        childWindow.ShowDialog();

当我调用ShowDialog()时,我收到此错误“调用线程无法访问此对象,因为其他线程拥有它。”。我知道这个错误是因为添加到子窗口的按钮是在后台线程上创建的,因此我们得到了这个错误。问题是:如何通过此错误并仍然在后台线程上创建我的按钮

1 个答案:

答案 0 :(得分:1)

每当您想从另一个线程访问Parent的窗口时,您必须每次都使用Dispatcher。我看到你的帖子的行动,你使用backgroundButton。因此,您必须对Dispathcer.BeginIvoke语句中的按钮执行任何操作 [编辑] 将线程操作更改为此

var t = new Thread(x =>
    {
        backgroundButton.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => backgroundButton = new Button { Content = "Child Button" }));
        childWindow.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(()                   => childWindow.MainPanel.Children.Add(backgroundButton)));
        manualResetEvents[0].Set();
    });

我是根据你的代码写的。我不会检查你的代码,但希望它是正确的。