修正嵌入资源的通用用户控件(Fix embedded resources for a generic

2019-09-01 08:31发布

在一个重构,我添加一个通用类型参数MyControl ,从派生的类用户控件 。 所以我的类现在是MyControl<T>

现在我会在运行时,说明该嵌入的资源文件MyControl`1.resources无法找到一个错误。 就让我们来看看与.net反射表明资源文件实际上是所谓MyControl.resources,没有`1。

在开始MyControl<T>.InitializeComponent方法有此线这可能是一个导致的问题:

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

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

Answer 1:

除了维姆的技术,你也可以声明具有相同的名称一般类非通用基本控制,并让您的通用控制/形式从非通用基类派生。

这样,您就可以欺骗既设计师和编译器使用到您的泛型类的资源文件,你会得到永久的设计师的支持,一旦基类的设置,而无需在您重建.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
{
     // ...
}

唯一的要求是为您的泛型类和它的基类具有完全相同的名称和基类必须在另一个类文件,否则设计师抱怨没有找到这两个类中的一个。

PS。 我与形式测试这一点,但它应该工作与对照组相同。



Answer 2:

事实证明,你可以覆盖资源文件名通过继承来加载ComponentResourceManager是这样的:

   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");

这似乎工作。

编辑 :上面的线被覆盖,如果您使用设计的,因为它是在生成的代码区域。 我避免了设计者和使用版本控制工具来恢复任何不需要的变化,但解决的办法是不理想的。



Answer 3:

在我的Visual Studio 2008中我有这样的错误:

System.ComponentModel.ComponentResourceManager资源=新System.ComponentModel.ComponentResourceManager(typeof运算(MyControl));

使用泛型类型“WindowsFormsApplication1.UserControl1”要求“1”类型的参数。

请注意,在我的情况下代码被不带括号产生, <>类名之后。

它正变得有趣,看到在一个普通用户控制的ImageList自动生成的实例非编译代码

他们说:

发布Microsoft在2005年7月6日在下午2点49分

这是一个有趣的bug。 你在一个通用的scneario,我们不会在Windows窗体设计器支持击中。 我们将无法在Whidbey的增加对这种支持(我注:Visual Studio 2008的?)版本。 我们会考虑这对未来的版本。 作为一种变通方法,您可以使用设计器创建一个没有通用的用户控件与公共类型属性,然后创建一个从它继承并通过牛逼到基类类型属性泛型类。

我想这种控制不能在Visual Studio窗体设计器来设计无论是。



Answer 4:

最简单的,最简单的解决方法是使虚拟类的自动生成typeof() 你不需要继承它,甚至把它暴露在外部的:

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

(根据我的经验,所需要的时间越来越设计师来解决仿制药是不值得的理想凉意泛型可以提供。我不会再使用一般的Windows窗体或控件来。)



文章来源: Fix embedded resources for a generic UserControl