WPF WindowsFormsHost Winform用户控件显示但不起作用

时间:2012-05-28 10:26:50

标签: c# wpf winforms visual-studio-2010

我正在尝试将现有的Winforms项目迁移到WPF中。但是:我需要保留一些用户控件作为WinForm控件。

我已将WinForms UserControl添加到WPF窗口中。它由RichTextBox和一些按钮和标签组成。这已经被子类化为各种其他用户控件。

当我将UserControl嵌入到WPF窗口中时,它会渲染 - 但是没有一个按钮似乎做任何事情。当基础流程更新时RichTextBox它不显示内容。然而,当我在调试中检查文本框时,我可以看到内容(虽然我必须点击'base'才能看到这个。)

[我发现的一个区别 - 虽然它可能不相关 - 是当这个控件在WPF上时,非工作的Visual Studio将对象显示为'密封'但是在原始的Winforms项目中它完全是工作它不显示密封。 ]

我添加了代码来更改标签中的文本 - 他们也坚决拒绝更新:如果我在调试模式下检查标签,我还能看到文本。

此堆栈溢出问题可能会解决同一问题: WindowsFormsHost Winform pdfviewer control problem

但答案对我来说没有多大意义: 它提到了替换

new Window { Content = CreateContent(), Title = title }.Show();

但这不是我承认的一段代码:我正在使用带有代码的xaml文件,并且使用

调用它
System.Windows.Application app = new System.Windows.Application(); 
app.Run(new FormWPFApp());

(其中FormWPFApp是WPF窗口的名称)

这是xaml标题: -

<Window x:Class="ZedApp.FormWPFApp"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Printers="clr-namespace:ZedApp.UserControls.Printers"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

        Title="Conversion version" Height="661" Width="1559" Loaded="Window_Loaded">

这是我用于两个UserControls的xaml(它们都从相同的基类继承): -

<WindowsFormsHost Height="430" HorizontalAlignment="Left" Margin="192,32,0,0" Name="windowsFormsHostTicketPrinter" VerticalAlignment="Top" Width="324" Grid.Row="1" Grid.Column="1">
    <Printers:TicketPrinter x:Name="ticketPrinter">
    </Printers:TicketPrinter>
</WindowsFormsHost>
<WindowsFormsHost Height="430" HorizontalAlignment="Left" Margin="522,32,0,0" Name="windowsFormsHostJournalPrinter" VerticalAlignment="Top" Width="324" Grid.Row="1" Grid.Column="1">
    <Printers:JournalPrinter x:Name="journalPrinter">
    </Printers:JournalPrinter>
</WindowsFormsHost>

[我注意到的另一件事是清除其中一个窗口上的Rich Text Box的方法,如果在WPF中的WindowsFormsHost下运行,则会开始输出以下类型的错误 - “在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。”

private void ClearRichTextBox(RichTextBox rtbToClear)
{
    if (rtbToClear.IsHandleCreated)
    {

        if (rtbToClear.InvokeRequired)
        {
            this.Invoke(new Action<RichTextBox>(ClearRichTextBox), new object[] {rtbToClear});
            return;
        }

        rtbToClear.Clear();
    }
}

导致此行为的可能原因是什么?我需要做些什么才能使用户控件中的元素正常工作?

1 个答案:

答案 0 :(得分:0)

与WinForms的正确输入互操作需要主机和WPF输入系统之间的一些合作。 SDK中Win32和WPF之间的topic消息循环很好地解释了这一点。在您的设置中,实现此目的的最简单方法是使用以下代码:

Window w = new Window1();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w);
w.Show();

ElementHost.EnableModelessKeyboardInterop()实际上是使用WinForms Application对象(通常运行消息循环)注册一个输入挂钩,并调用ComponentDispatcher.RaiseThreadMessage()。