views:

823

answers:

8

Helo,

I would like a stuff like that :

public partial class ObjectSelectorControl<T> : UserControl where T : class

The problem is that the designer can't resolve this. Someone as a workaround with this ?

A: 

What happens when you remove

where T : class
Charlie Salts
Still can use the designer. I got the following error : Could not find type 'T'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built.
Toto
This won't work, the issue is with the class being generic, not the generic constraints.
Adam Robinson
+1  A: 

There are some restrictions on what your control can or cannot do in order to be able to use the designer. Fundamentally they all revolve around the designer being able to instantiate your class (must have a parameterless constructor, can't be abstract, etc.). Because the designer has no idea what type to pass as a generic argument (and I doubt this is even a consideration), your class can't be instantiated.

Your best hope would be to create your UserControl and change the constructor to protected (this, I believe, will work, since the designer uses reflection and ignores visibility, but I'm not 100% positive). You can then inherit from that UserControl and create your generic class and call the base (protected) constructor.

Adam Robinson
A: 

I don't believe this is possible, because the designer invokes an instance of your class. If you use generics, the designer doesn't know what type to pass into 'T'.

Jake Pearson
+1  A: 

Sounds much like what we do in our project.

There's a base class that is generic:

public partial class controlItemList<TBaseItem, TBaseItemCollection> : UserControl, IUIDispatcher
 where TBaseItem : new()
 where TBaseItemCollection : IItemCollection<TBaseItem>

Then for each use we define a non-generic version (which still couldn't be used by designer):

public class controlMessagesNonGenericParent : controlItemList<MailItem, MailItemCollection>
{
}

... and then we have derived controls that could be used in designer:

public partial class controlMessages : controlMessagesNonGenericParent
{
...
}
Filip Navara
It seems like you're going the opposite direction, though. You have a generic base and you're creating specific concrete implementations for the designer. It sounds like he wants to create a generic control and design it.
Adam Robinson
You are right, but using a generic class as control directly is impossible. That's why we subclass it, so it can be used in the designer. The fact that the subclassed versions modify the behavior is irrelevant here.
Filip Navara
Right, it is impossible, but it doesn't appear to address his problem. This isn't a "hack" that will allow him to get around the problem. Indeed, it seems that the solution goes in the OTHER direction (create a control that ISN'T generic, do the design, then subclass it and make it generic) makes more sense. I don't see how this solves anything.
Adam Robinson
The generic control CAN be opened in the designer! It's instance CAN'T be placed on a form directly though.
Filip Navara
Damn spelling mistakes, sorry ;) With the code I posted above, both controlItemList and controlMessages can be opened as controls in the designer. Only controlMessages can be placed in the toolbox and used though.
Filip Navara
A: 

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105876

The bug has been posted to microsoft's site and you can see that its marked as "Postponed" currently there is no solution !! .

Akash Kava
Doesn't really seem like a "bug", it's a consequence of using generics. Perhaps they can provide a future enhancement that allows you to select a type to be supplied, but I wouldn't classify it as a "bug".
Adam Robinson
A: 

Use composition instead of generics. Instead of using ObjectSelectorControl, give a generic member of another type (Selector<T> maybe) and act on that object instead of trying to force yourself to be generic.

CaptnCraig
+5  A: 

This works

public class Control1<T> : UserControl { ... }

public class Control2 : Control1<double> { ... }

public class Control3 : Control2 { ... }

had read it here:

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/0c265543-d6f0-41f6-beeb-b89e0071c5c3

P.K
+1 Practically the same solution as I suggested, but described more cleanly.
Filip Navara
yep it works and it was what I was looking for.
Toto
A: 

Same problem, i resolved with a wrap class

public partial class MyUserControl<T> : UserControl where T : class


public class MyUserControlWrapper : MyUserControl<MyClass>


public class MyUserControlWorking : MyUserControlWrapper

On MyUserControlWorking IDE working fine (on MyUserControlWrapper as error).

Hope help u.

Zax
Exactly the same answer as the already given and as accepted marked answer 269 days before yours.
Oliver