我正在尝试将现有的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();
}
}
导致此行为的可能原因是什么?我需要做些什么才能使用户控件中的元素正常工作?
答案 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()。