C# generics usercontrol
Asked Answered
P

7

31

I would like to define the following control:

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

The problem is that the designer can't resolve this. Is there a workaround to this issue?

Puggree answered 25/8, 2009 at 16:24 Comment(2)
When you tried it, how did you declare the class on xaml?Fitment
Starting from VS 2015.1, Windows Forms Designer shows classes which have generic base class without any problem. See example.Charter
L
38

This works

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

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

public class Control3 : Control2 { ... }

had read it here:

Generic User Controls?

Loch answered 25/8, 2009 at 16:34 Comment(5)
+1 Practically the same solution as I suggested, but described more cleanly.Eldenelder
Make sure to have Control3 in a separate file.Catrinacatriona
I used to have this workaround working. But now it doesn't, not sure why but I found out the solution is "we need to go deeper". I added even one more level and it worked again, so basically like, "public class Control4 : Control3 { ... }".Drida
The "proxy" classes could be declared in the same file. See answer here: #2547199Unprecedented
Starting from VS 2015.1, Windows Forms Designer shows classes which have generic base class without any problem. See example.Charter
E
12

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
{
...
}
Eldenelder answered 25/8, 2009 at 16:30 Comment(5)
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.Nexus
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.Eldenelder
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.Nexus
The generic control CAN be opened in the designer! It's instance CAN'T be placed on a form directly though.Eldenelder
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.Eldenelder
N
3

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.

Nexus answered 25/8, 2009 at 16:27 Comment(0)
W
2

I don't know at which point (with which C#/.NET/VS verison update), but now it is possible to create generic control the same way you create any other generic class.

If you create your UserControl in VS the standard way (i.e. by adding it through GUI), you simply add <T> in both parts of class declaration ("base" class code and the designer managed file). Actually, that is what you have in your quoted code.

Whiles answered 13/7, 2018 at 6:30 Comment(1)
This does not work in .net core. It works in framework only.Prig
P
0

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'.

Petuntse answered 25/8, 2009 at 16:28 Comment(0)
M
0

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 !! .

Masticatory answered 25/8, 2009 at 16:30 Comment(1)
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".Nexus
C
-1

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.

Classicism answered 25/8, 2009 at 16:31 Comment(2)
Maybe I am wrong but if you use composition inside your UserControl: a) You must specify the type of the generic attribute or b) you must make you class generic too so I don't get what you mean.Fitment
Composition is not a replacement technique for generics. Maybe a solution to make WinForms work with generics can be devised, involving composition, but in that case your answer doesn't indicate any direction.Aquaplane

© 2022 - 2024 — McMap. All rights reserved.