修复通用UserControl的嵌入资源

在重构期间,我向MyControl添加了一个generics类型参数, MyControl是一个派生自UserControl的类。 所以我的class级现在是MyControl

现在我在运行时收到一条错误,指出无法找到嵌入式资源文件MyControl`1.resources 。 使用.NET Reflector快速查看显示资源文件实际上名为MyControl.resources ,没有`1

MyControl.InitializeComponent方法的开头,有一行可能是导致问题的那一行:

  System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager( typeof(MyControl)); 

如何强制ComponentResourceManager使用嵌入式资源文件MyControl.resources ? 其他解决此问题的方法也是受欢迎的。

除了Wim的技术之外,您还可以声明与generics类具有相同名称的非generics基本控件,并使您的通用控件/表单派生自该非generics基类。

通过这种方式,您可以欺骗设计人员和编译器使用通用类中的资源文件,并且一旦设置了基类,您就可以获得永久的设计器支持,而无需在每次重建时都使用.designer文件:

 // Empty stub class, must be in a different file (added as a new class, not UserControl // or Form template) public class MyControl : UserControl { } // Generic class public class MyControl : MyControl { // ... } 

唯一的要求是为您的generics类及其基类提供完全相同的名称,并且基类必须位于另一个类文件中,否则设计者会抱怨没有找到这两个类中的一个。

PS。 我用表单测试了这个,但它应该与控件一样。

事实certificate,您可以通过inheritanceComponentResourceManager来覆盖要加载的资源文件名,如下所示:

  using System; using System.ComponentModel; internal class CustomComponentResourceManager : ComponentResourceManager { public CustomComponentResourceManager(Type type, string resourceName) : base(type) { this.BaseNameField = resourceName; } } 

现在我可以确保资源管理器像这样加载MyControl.resources

  System.ComponentModel.ComponentResourceManager resources = new CustomComponentResourceManager(typeof(MyControl<>), "MyControl"); 

这似乎有效。

编辑 :如果您使用设计器,则会覆盖上面的行,因为它位于生成的代码区域中。 我避免使用设计器并使用版本控制工具来恢复任何不需要的更改,但解决方案并不理想。

在我的Visual Studio 2008上,我有这个错误:

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MyControl));

使用generics类型’WindowsFormsApplication1.UserControl1’需要’1’类型参数。

请注意,在我的情况下,代码是在没有括号的情况下生成的, <> ,在类名后面。

它变得有趣,请参阅ImageList在通用用户控件中自动生成非编译代码

他们说了什么:

Microsoft于2005年7月6日下午2:49发布

这是一个有趣的错误。 您已经遇到了我们在Windows窗体设计器中不支持的通用scneario。 我们将无法在Whidbey(我的注释:Visual Studio 2008?)版本中添加对此的支持。 我们将考虑将其用于未来版本。 作为一种变通方法,您可以使用设计器创建一个具有公共Type属性的非genericsUserControl,然后创建一个inheritance自它的generics类,并将T传递给基类Type属性。

我想这个控件也不能在Visual Studio窗体设计器中设计。

最简单和最简单的解决方法是为自动生成的typeof()创建一个虚拟类。 您不需要inheritance它,甚至不需要将它暴露给外部:

 // Non-generic name so that autogenerated resource loading code is happy internal sealed class GridEditorForm { } 

(根据我的经验,让设计师围绕仿制药工作所需的时间并不值得理想的冷却仿制品所能提供的。我不会再使用通用的Windows窗体或控件。)