Frage

Während ein Refactoring, habe ich einen generischen Typ-Parameter auf MyControl, eine Klasse, die von Usercontrol . So ist meine Klasse jetzt MyControl<T>.

Jetzt bekomme ich einen Fehler zur Laufzeit des besagt, dass die eingebettete Ressource-Datei MyControl`1.resources kann nicht gefunden werden. Ein kurzer Blick mit .NET Reflector zeigt, dass die Ressource-Datei genannt wird eigentlich MyControl. Ressourcen , ohne die `1 .

Zu Beginn der MyControl<T>.InitializeComponent Methode gibt es diese Linie, die wahrscheinlich derjenige ist, Probleme zu verursachen:

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

Wie erzwinge ich die ComponentResourceManager die eingebettete Ressource-Datei MyControl.resources zu benutzen? Andere Möglichkeiten, dieses Problem zu lösen, sind ebenfalls willkommen.

War es hilfreich?

Lösung

Neben Wim sprühte, können Sie auch eine nicht-generische Basissteuer erklären, die den gleichen Namen wie die generische Klasse hat, und lassen Sie Ihre allgemeine Steuer / Form ergeben sich aus dieser nicht-generische Basisklasse.

Auf diese Weise können sowohl die Designer Trick und den Compiler in die Ressource-Datei von Ihrem generischen Klasse verwenden und permanente Designer Unterstützung erhalten, sobald die Basisklasse Setup ist, ohne in der .designer Datei jedes Mal Geige, Sie neu zu erstellen:

// 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
{
     // ...
}

Die einzigen Voraussetzungen sind haben genau die gleichen Namen für die generische Klasse und Basisklasse, und dass die Basisklasse in einer anderen Klasse-Datei sein muss, da sonst die Designer beschwert finden über nicht einer von die beiden Klassen.

PS. Getestet habe ich diese mit Formen, aber es soll das gleiche mit Kontrollen funktionieren.

Andere Tipps

Es stellte sich heraus können Sie die Ressourcendateinamen überschreiben, indem erben von ComponentResourceManager wie folgt zu laden:

   using System;
   using System.ComponentModel;

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

Jetzt kann ich sicherstellen, dass die Ressourcen-Manager Lasten wie diese MyControl.resources:

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

Dies scheint zu funktionieren.

Bearbeiten : die obige Zeile überschrieben wird, wenn Sie den Designer verwenden, weil es in der ist erzeugten Coderegion. Ich vermeide die Designer und die Verwendung von Versionskontrolle Tool machen, um unerwünschte Änderungen rückgängig machen, aber die Lösung ist nicht ideal.

Auf meinem Visual Studio 2008 ich diesen Fehler haben:

  

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

Mit dem generischen Typ 'WindowsFormsApplication1.UserControl1' '1' Typ Argumente erfordert.

Beachten Sie, dass Code in meinem Fall wurde ohne Klammern erzeugt, <>, nach dem Klassennamen.

Es wird immer interessanter finden Sie unter Abbildungsliste generiert automatisch nicht Code in einer Benutzersteuerung Kompilieren .

Was sie sagten:

  

Veröffentlicht von Microsoft am 2005.07.06 um 2:49 Uhr

     

Das ist ein interessanter Bug. Sie haben auf einem generischen scneario getroffen, die wir in der Windows Forms-Designer nicht unterstützen. Release: Wir werden Unterstützung nicht in der Whidbey (Visual Studio 2008? meine Anmerkung) für diese Lage, hinzuzufügen. Wir betrachten dies für eine zukünftige Version. Als Abhilfe können Sie den Designer verwenden, um eine generischen keine Usercontrol mit einer öffentlichen Typ Eigenschaft zu erstellen und dann eine generische Klasse erstellen, die von erbt und übergibt T in die Basisklassen Type-Eigenschaft.

Ich nehme diese Kontrolle kann auch nicht in der Visual Studio-Formulardesigner entworfen werden.

Die einfachste und einfachste Abhilfe ist, eine Dummy-Klasse für die automatisch generierte typeof() zu machen. Sie müssen nicht von ihm erben oder sogar nach außen aussetzen:

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

(Nach meiner Erfahrung ist die Zeit, die Designer immer um Generika zu arbeiten nicht wert war die ideale Kühle Generika bieten kann. Ich werde nicht generic Fenster Formulare oder Steuerelemente wieder werden.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top