C# NET Core 3.1 WinForms Designer与WPF用户控件不兼容
一年多前,我开始使用Windows窗体编写.NET Framework 4.6.1应用程序。当时我知道WPF,但熟悉Windows窗体,它拥有我所需要的大部分控件。对于缺少的控件,我在Windows窗体中编写了两个,在WPF中编写了一个。所有这些都很好地共存,WPF控件在一个元素宿主中进行了容器化 本周,我开始迁移到.NETCore3.1。我对项目副本的测试是肯定的,实际迁移的初始结果也是肯定的。经过小规模的重构,解决方案构建并运行时没有问题。然后,在WinForms Designer中打开主UI表单后,小精灵出现了。回到.NETFramework,我的所有自定义控件都出现在设计器的工具箱中,可以方便地拖放到窗体上。在.NETCore中,工具箱中只显示WinForms控件,而不显示WPF控件。因为设计器看不到该控件,所以将其从窗体的设计器代码中剥离,留下一个空的元素宿主 这是踢球的人。恢复设计器的更改后,接受对窗体设计器代码的任何直接手动编辑,生成项目成功并运行良好。因此,出于某种原因,设计者不喜欢WinForms中的WPF控件 我尝试过的事情:C# NET Core 3.1 WinForms Designer与WPF用户控件不兼容,c#,wpf,winforms,.net-core,C#,Wpf,Winforms,.net Core,一年多前,我开始使用Windows窗体编写.NET Framework 4.6.1应用程序。当时我知道WPF,但熟悉Windows窗体,它拥有我所需要的大部分控件。对于缺少的控件,我在Windows窗体中编写了两个,在WPF中编写了一个。所有这些都很好地共存,WPF控件在一个元素宿主中进行了容器化 本周,我开始迁移到.NETCore3.1。我对项目副本的测试是肯定的,实际迁移的初始结果也是肯定的。经过小规模的重构,解决方案构建并运行时没有问题。然后,在WinForms Designer中打开主U
- 在测试过程中,我发现WinForms主UI需要将“UseWindowsForms”和“UseWPF”设置为“true”才能编译项目。然后,我将“UseWindowsForms”参数添加到WPF用户控件库中。这导致该控件出现在设计器的工具箱中,但尝试添加该控件导致此错误:“未能创建组件。。。Microsoft.DotNet.DesignTools.Client.DesignTools服务器异常。。。确保该类型实现IComponent并提供适当的公共构造函数。适当的构造函数要么不接受任何参数,要么只接受一个IContainer参数。“代码中现有的WPF控件仍然被删除
- 我将WPF控件从库复制到主UI项目,编辑了名称空间,并删除了库项目引用。结果与上面相同
- 创建了一个新的Windows窗体用户控件库,将“UseWPF”添加到项目中,并将WPF控件复制到此库。结果与上面相同
- 回到我的项目的测试副本,我遵循了微软的“尝试转换”和“升级助手”指南。后者起初似乎很有希望,因为它替换、修改或删除了过时的引用和软件包。但没有成功
- 使用.NET Core 3.1和.NET 5尝试了上述迁移步骤。结果相同
我终于想出了一个解决办法;这个想法是由ElementHost控件的Microsoft文档页面引发的: 本质上,将WPF控件宿主从主UI移动到WinForms控件库中。因此,此WinForms控件库中的用户控件将是WPF控件的包装器。以下是我在测试VS解决方案中采取的步骤:
using System;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
namespace WinFormsLibrary
{
public partial class WpfTest : UserControl
{
// ElementHost for the WPF control
private ElementHost host = new ElementHost();
// WPF control to be hosted
private WpfControlLibrary31.TestControl31 uc = new WpfControlLibrary31.TestControl31();
public WpfTest()
{
InitializeComponent();
}
private void WpfTest_Load(object sender, EventArgs e)
{
// set the docking style for the ElementHost
host.Dock = DockStyle.Fill;
// add the WPF control as a child of ElementHost
host.Child = uc;
// add the ElementHost as a control of the panel container
panelWpf.Controls.Add(host);
}
}
}