views:

355

answers:

2

During a refactoring, I added a generic type parameter to MyControl, a class derived from UserControl. So my class is now MyControl<T>.

Now I get an error at runtime stating that the embedded resource file MyControl`1.resources cannot be found. A quick look with reflector shows that the resource file is actually called MyControl.resources, without the `1.

At the start of the MyControl<T>.InitializeComponent method there is this line which is probably the one causing problems:

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

How do I force the ComponentResourceManager to use the embedded resource file MyControl.resources? Other ways to resolve this issue are also welcome.

+1  A: 

on my vs2008 I have this error

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

Using the generic type 'WindowsFormsApplication1.UserControl1' requires '1' type arguments

Notice that in my case there code was generated without parens

<>
after class name

It becoming interesting ...

What they said

Posted by Microsoft on 7/6/2005 at 2:49 PM This is an interesting bug. You've hit upon a generic scneario that we do not support in the Windows Forms designer. We will not be able to add support for this in the Whidbey(my note: vs2008?) release. We will consider this for a future version. As a workaround, you can use the designer to create a none generic UserControl with a public Type property and then create a generic class that inherits from it and passes T into the base classes Type property

i suppose this control cannot be designed in VS forms designer too

Trickster
The designer doesn't have any problem, because it instantiates the parent class (UserControl) (not MyControl<T>) and then puts the child controls on that surface itself. But you are right that it would become a problem if I derived AnotherControl<T> from MyControl<T>.
Wim Coenen
But i dont know how to sort out problem with resources. Looks like a bug. But so old bug (
Trickster
Hmm. vs2010 cannot do it too ((
Trickster
+2  A: 

Turns out you can override the resource filename to load by inheriting from ComponentResourceManager like this:

   using System;
   using System.ComponentModel;

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

Now I can make sure that the resource manager loads MyControl.resources like this:

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

This seems to work.

edit: the above line is overwritten if you use the designer, because it is in the generated code region. I avoid the designer and make use of version control tools to revert any unwanted changes, but the solution is not ideal.

Wim Coenen