Hat jemand eine nützliche Lösung für das DesignMode-Problem bei der Entwicklung von Steuerelementen gefunden?
Das Problem ist, dass DesignMode nur für die erste Ebene funktioniert, wenn Sie Steuerelemente verschachteln. Die zweite und untere Ebene von DesignMode gibt immer FALSE zurück.
Der Standard-Hack bestand darin, den Namen des laufenden Prozesses zu überprüfen. Wenn es sich um "DevEnv.EXE" handelt, muss es sich um Studio handeln, damit DesignMode wirklich WAHR ist.
Das Problem dabei ist, dass der Prozessname nach der Registrierung und anderen seltsamen Teilen durchsucht wird. Das Endergebnis ist, dass der Benutzer möglicherweise nicht über die erforderlichen Rechte verfügt, um den Prozessnamen anzuzeigen. Außerdem ist diese seltsame Route sehr langsam. Wir mussten also zusätzliche Hacks stapeln, um einen Singleton zu verwenden. Wenn bei der Abfrage des Prozessnamens ein Fehler auftritt, wird davon ausgegangen, dass DesignMode FALSE ist.
Ein guter, sauberer Weg, um DesignMode zu bestimmen, ist in Ordnung. Es wäre sogar noch besser, Microsoft dazu zu bringen, das Problem intern im Framework zu beheben!
quelle
Antworten:
Bei erneuter Betrachtung dieser Frage habe ich nun 5 verschiedene Möglichkeiten entdeckt, dies zu tun:
Um die drei vorgeschlagenen Lösungen in den Griff zu bekommen, habe ich eine kleine Testlösung erstellt - mit drei Projekten:
Ich habe dann das SubSubControl in das SubControl eingebettet, dann jeweils eines in die TestApp.Form.
Dieser Screenshot zeigt das Ergebnis beim Ausführen.
Dieser Screenshot zeigt das Ergebnis mit dem in Visual Studio geöffneten Formular:
Schlussfolgerung: Es scheint, dass ohne Reflexion LicenseUsage die einzige ist, die innerhalb des Konstruktors zuverlässig ist, und die einzige, die außerhalb des Konstruktors zuverlässig ist, ist 'IsDesignedHosted' (von BlueRaja unten).
PS: Siehe den folgenden Kommentar von ToolmakerSteve (den ich nicht getestet habe): "Beachten Sie, dass die Antwort von IsDesignerHosted aktualisiert wurde, um LicenseUsage ... einzuschließen. Der Test kann nun einfach if (IsDesignerHosted) sein. Ein alternativer Ansatz ist das Testen von LicenseManager im Konstruktor und das Ergebnis zwischenspeichern . "
quelle
if(LicenseUseage == LicenseUsageMode.Designtime || IsDesignerHosted)
wäre also der 100% richtige Ansatz?LicenseUsage...
, dass sie jetzt enthalten ist. Der Test kann nun einfach durchgeführt werdenif (IsDesignerHosted)
. Ein alternativer Ansatz besteht darin , LicenseManager im Konstruktor zu testen und das Ergebnis zwischenzuspeichern .Von dieser Seite :
( [Edit 2013] Bearbeitet, um in Konstruktoren mit der von @hopla bereitgestellten Methode zu arbeiten.)
Ich habe einen Fehlerbericht bei Microsoft eingereicht . Ich bezweifle, dass es irgendwohin gehen wird, aber stimmen Sie es trotzdem ab, da dies offensichtlich ein Fehler ist (unabhängig davon, ob es " beabsichtigt" ist oder nicht ).
quelle
Warum überprüfen Sie nicht LicenseManager.UsageMode? Diese Eigenschaft kann die Werte LicenseUsageMode.Runtime oder LicenseUsageMode.Designtime haben.
Wenn Code nur zur Laufzeit ausgeführt werden soll, verwenden Sie den folgenden Code:
quelle
Dies ist die Methode, die ich in Formularen verwende:
Auf diese Weise ist das Ergebnis auch dann korrekt, wenn eine der DesignMode- oder LicenseManager-Eigenschaften fehlschlägt.
quelle
Ich verwende die LicenseManager-Methode, speichere aber den Wert des Konstruktors für die Verwendung während der gesamten Lebensdauer der Instanz zwischen.
VB-Version:
quelle
Wir verwenden diesen Code mit Erfolg:
quelle
Mein Vorschlag ist eine Optimierung der Antwort @ blueraja-danny-pflughoeft . Diese Lösung berechnet das Ergebnis nicht jedes Mal, sondern nur beim ersten Mal (ein Objekt kann den UsageMode nicht vom Entwurf zur Laufzeit ändern).
quelle
Ich bin selbst noch nie davon überrascht worden, aber können Sie nicht einfach die übergeordnete Kette von der Steuerung zurückgehen, um zu sehen, ob DesignMode irgendwo über Ihnen eingestellt ist?
quelle
Da keine der Methoden zuverlässig (DesignMode, LicenseManager) oder effizient (Prozess, rekursive Prüfungen) ist, verwende ich eine
public static bool Runtime { get; private set }
auf Programmebene und setze sie explizit in die Main () -Methode.quelle
DesignMode ist eine private Immobilie (soweit ich das beurteilen kann). Die Antwort besteht darin, eine öffentliche Eigenschaft bereitzustellen, die die DesignMode-Requisite verfügbar macht. Anschließend können Sie die Kette der Benutzersteuerelemente kaskadieren, bis Sie auf ein Nichtbenutzersteuerelement oder ein Steuerelement stoßen, das sich im Entwurfsmodus befindet. Etwas wie das....
Wo alle Ihre UserControls von MyBaseUserControl erben. Alternativ können Sie eine Schnittstelle implementieren, die den "RealDeisgnMode" verfügbar macht.
Bitte beachten Sie, dass es sich bei diesem Code nicht um Live-Code handelt. :) :)
quelle
Ich hatte nicht bemerkt, dass Sie Parent.DesignMode nicht aufrufen können (und ich habe auch in C # etwas über "geschützt" gelernt ...)
Hier ist eine reflektierende Version: (Ich vermute, dass es einen Leistungsvorteil gibt, designModeProperty zu einem statischen Feld zu machen.)
quelle
Ich musste dieses Problem kürzlich in Visual Studio 2017 bekämpfen, wenn ich verschachtelte UserControls verwendete. Ich kombiniere mehrere der oben und anderswo erwähnten Ansätze und optimiere dann den Code, bis ich eine anständige Erweiterungsmethode habe, die bisher akzeptabel funktioniert. Es führt eine Folge von Überprüfungen durch und speichert das Ergebnis in statischen booleschen Variablen, sodass jede Überprüfung zur Laufzeit höchstens einmal durchgeführt wird. Der Prozess mag übertrieben sein, verhindert jedoch, dass der Code im Studio ausgeführt wird. Hoffe das hilft jemandem.
quelle