修复通用UserControl的嵌入资源

Wim*_*nen 23 .net c# generics designer winforms

在重构期间,我添加了一个泛型类型参数MyControl,一个派生自UserControl的类.所以我的班级现在MyControl<T>.

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

在该MyControl<T>.InitializeComponent方法的开头有这条线可能是引起问题的线:

 System.ComponentModel.ComponentResourceManager resources =
    new System.ComponentModel.ComponentResourceManager(
       typeof(MyControl<>));
Run Code Online (Sandbox Code Playgroud)

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

Wim*_*nen 18

事实证明,您可以通过继承ComponentResourceManager如下来覆盖要加载的资源文件名:

   using System;
   using System.ComponentModel;

   internal class CustomComponentResourceManager : ComponentResourceManager
   {
      public CustomComponentResourceManager(Type type, string resourceName)
         : base(type)
      {
         this.BaseNameField = resourceName;
      }
   }
Run Code Online (Sandbox Code Playgroud)

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

 System.ComponentModel.ComponentResourceManager resources =
    new CustomComponentResourceManager(typeof(MyControl<>), "MyControl");
Run Code Online (Sandbox Code Playgroud)

这似乎有效.

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

  • 为了帮助其他人谷歌搜索,我终于找到了解决我在运行时接收MissingManifestResourceException的问题的解决方案,当我的Form <T> .Designer.cs文件尝试使用resources.GetObject加载图标时.这是使用.NET 3.5/VS2010.谢谢! (4认同)

T. *_*bre 16

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

通过这种方式,您可以欺骗设计人员和编译器使用泛型类中的资源文件,并且一旦设置了基类,您就可以获得永久的设计器支持,而无需在每次重建时都使用.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<T> : MyControl
{
     // ...
}
Run Code Online (Sandbox Code Playgroud)

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

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