从WinForms BackgroundWorker创建WPF窗口 [英] Creating a WPF Window from a WinForms BackgroundWorker

查看:88
本文介绍了从WinForms BackgroundWorker创建WPF窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF dll,其中包含许多Window类,并公开了显示那些窗口的方法.

I have a WPF dll that contains a number of Window classes and exposes methods that display those windows.

我还有一个单独的WinForms项目,该项目正在BackgroundWorker组件的DoWork方法内的WPF项目中调用这些方法之一.

I also have a separate WinForms project that is calling one of those methods in the WPF project inside the DoWork method of a BackgroundWorker component.

在实例化WPF窗口的代码行上,出现以下运行时错误:

On the line of code that instantiates a WPF Window, I get the following runtime error:

调用线程必须是STA,因为许多UI组件都需要STA.

The calling thread must be STA, because many UI components require this.

通过Google搜索,我可以此讨论. (结果是Jon Skeet除了Stack Overflow之外还回答了其他网站上的问题!)他链接到

A google search let me to this discussion. (Turns out Jon Skeet answers questions on other sites in addition to Stack Overflow!) He linked to this article, which states

BackgroundWorker组件与WPF配合使用...

The BackgroundWorker component works well with WPF ...

该文章还提到了使用DispatcherObject类,但是我不了解如何进行该工作,我宁愿继续使用BackgroundWorker组件.

That article also mentions using the DispatcherObject class, but I don't understand how to make that work and I would rather just continue using my BackgroundWorker component.

作为测试用例,我想出了以下代码来重现该错误.在WPF类库中,这是Window1.xaml.vb

As a test case, I came up with the following code to reproduce the error. In the WPF class library, here is the code in Window1.xaml.vb

Partial Public Class Window1

    Public Shared Function ShowMe() As Boolean?
        Dim w = New Window1 'Error appears on this line.
        Return w.ShowDialog()
    End Function

End Class

在WinForms应用程序中,这是Form1.vb中的代码

In the WinForms application, here is the code in Form1.vb

Imports System.ComponentModel

Public Class Form1

    Private WithEvents worker As BackgroundWorker
    Private Sub doWord(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles worker.DoWork
        WpfLibrary.Window1.ShowMe()
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        worker = New BackgroundWorker
        worker.RunWorkerAsync()
    End Sub
End Class

即使将BackgroundWorker组件放置在Window1.xaml.vb本身中,也会发生相同的错误.那么,那篇文章是错误的,我真的不能在WPF中使用BackgroundWorker吗?还是我需要做一些其他工作才能使它正常工作?

Even when the BackgroundWorker component is placed in Window1.xaml.vb itself, the same error occurs. So, is that article wrong and I can't really use a BackgroundWorker with WPF? Or is there something else I need to do to get it to work?

如果BackgroundWorker无法正常工作,那么我该如何替换上面Form1.vb中的代码以改用Dispatcher?

If the BackgroundWorker won't work, then how would I replace the code in Form1.vb above to use a Dispatcher instead?

推荐答案

可以在WPF中使用后台工作者,这不是您的问题.

You can use a background worker with WPF, that's not your problem.

您的问题是,您无法在Winform或WPF应用程序中执行任何从主UI线程外部更新UI的任务,并且BackgroundWorker的DoWork方法在另一个线程中运行.

Your problem is that you can't perform any task that updates the UI from outside of the main UI thread in either a winform or WPF application and the BackgroundWorker's DoWork method is running in a different thread.

因此,在启动BackgroundWorker之前或在其RunWorkerCompleted事件中,必须在BackgroundWorker的后台线程之外打开新窗口.

Therefore you must open the new window outside of the BackgroundWorker's background thread, either before you start the BackgroundWorker, or in its RunWorkerCompleted event.

在不知道打开窗口的调用周围的代码的情况下,我很难进一步提意见,但我希望这会为您指明正确的方向.

Without knowing the code that surrounds the call to open the window it is difficult for me to advise further, but I hope that points you in the right direction.

这篇关于从WinForms BackgroundWorker创建WPF窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆