2009-08-25 14 views
22

Ich mag die folgende Kontrolle definieren:C# Generika Usercontrol

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

Das Problem ist, dass der Designer dies nicht auflösen kann. Gibt es eine Problemumgehung für dieses Problem?

+1

Wenn Sie es einmal, wie haben Sie die Klasse auf XAML deklarieren? –

Antwort

31

Dies funktioniert

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

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

public class Control3 : Control2 { ... } 

hatte es hier lesen:

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

+2

+1 Praktisch die gleiche Lösung wie ich vorgeschlagen habe, aber sauberer beschrieben. –

+0

Yep es funktioniert und es war was ich suchte. – Toto

+0

Stellen Sie sicher, Control3 in einer separaten Datei zu haben. –

1

Es gibt einige Einschränkungen, was Ihre Kontrolle tun kann oder nicht kann, um den Designer verwenden zu können. Im Grunde drehen sich alle um den Designer, der in der Lage ist, Ihre Klasse zu instanziieren (muss einen parameterlosen Konstruktor haben, kann nicht abstract, etc. sein). Da der Designer keine Ahnung hat, welcher Typ als generisches Argument übergeben werden soll (und ich bezweifle, dass dies überhaupt eine Überlegung ist), kann Ihre Klasse nicht instanziiert werden.

Ihre beste Hoffnung wäre, Ihre UserControl zu erstellen und den Konstruktor zu ändern protected (das, glaube ich, wird funktionieren, da der Designer Reflexion verwendet und Sichtbarkeit ignoriert, aber ich bin nicht 100% positiv). Sie können dann von diesem UserControl erben und Ihre generische Klasse erstellen und den Basis (protected) -Konstruktor aufrufen.

0

Ich glaube nicht, dass dies möglich ist, weil der Designer eine Instanz Ihrer Klasse aufruft. Wenn Sie Generika verwenden, weiß der Designer nicht, welcher Typ in "T" übergeben werden soll.

8

Klingt sehr ähnlich wie das, was wir in unserem Projekt machen.

Es gibt eine Basisklasse, die generisch ist:

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

Dann für jede Verwendung wir eine nicht-generische Version definieren (die immer noch nicht von Designern verwendet werden):

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

. wir haben abgeleitete Kontrollen .. und dann die in Designern verwendet werden könnte:

public partial class controlMessages : controlMessagesNonGenericParent 
{ 
... 
} 
+1

Es sieht so aus, als ob Sie in die entgegengesetzte Richtung gehen. Sie haben eine generische Basis und Sie erstellen konkrete konkrete Implementierungen für den Designer. Es klingt, als ob er ein generisches Steuerelement erstellen und gestalten möchte. –

+1

Sie haben Recht, aber die Verwendung einer generischen Klasse als direkte Kontrolle ist unmöglich. Deshalb unterklassifizieren wir es, damit es im Designer verwendet werden kann. Die Tatsache, dass die Unterklassen das Verhalten modifizieren, ist hier irrelevant. –

+1

Richtig, es ist unmöglich, aber es scheint nicht sein Problem anzugehen.Dies ist kein "Hack", mit dem er das Problem umgehen kann. Tatsächlich scheint es, dass die Lösung in die andere Richtung geht (ein Steuerelement erstellen, das NICHT generisch ist, das Design macht, dann die Unterklasse und es generisch macht) macht mehr Sinn. Ich sehe nicht, wie das alles löst. –

0

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

Der Fehler wurde auf Microsofts Website gepostet und Sie können sehen, dass es als "Verschoben" gekennzeichnet ist, derzeit gibt es keine Lösung !! .

+0

Scheint wirklich nicht wie ein "Bug", es ist eine Konsequenz der Verwendung von Generika. Vielleicht können sie eine zukünftige Verbesserung bieten, die es Ihnen ermöglicht, einen Typ auszuwählen, der geliefert werden soll, aber ich würde es nicht als "Fehler" einstufen. –

0

Verwenden Sie die Zusammensetzung anstelle von Generika. Anstatt ObjectSelectorControl zu verwenden, geben Sie ein generisches Element eines anderen Typs (Selector<T> vielleicht) und agieren für dieses Objekt, anstatt zu versuchen, sich selbst als generisch zu definieren.

+1

Vielleicht irre ich mich, aber wenn Sie Zusammensetzung in Ihrem UserControl verwenden: a) Sie müssen den Typ des generischen Attributs angeben oder b) Sie müssen Sie auch generische Klasse machen, damit ich nicht verstehe, was Sie meinen. –

+0

Zusammensetzung ist keine Ersatztechnik für Generika. Vielleicht kann eine Lösung entwickelt werden, um WinForms mit Generika zu arbeiten, die eine Komposition beinhalten, aber in diesem Fall gibt Ihre Antwort keine Richtung an. – MarioDS