web-dev-qa-db-fra.com

Détection du mode de conception à partir du constructeur d'un contrôle

Suite à cette question , est-il possible de détecter si on est en mode conception ou en mode exécution à partir du constructeur d'un objet?

Je me rends compte que ce n'est peut-être pas possible et que je devrai changer ce que je veux, mais pour l'instant je m'intéresse à cette question spécifique.

88
nwahmaet

Vous pouvez utiliser l'énumération LicenceUsageMode dans l'espace de noms System.ComponentModel:

bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
174
adrianbanks

Cherchez-vous quelque chose comme ça:

public static bool IsInDesignMode()
{
    if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1)
    {
        return true;
    }
    return false;
}

Vous pouvez également le faire en vérifiant le nom du processus:

if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
   return true;
22
Jarek

Composant ... autant que je sache n'a pas la propriété DesignMode. Cette propriété est fournie par Control. Mais le problème est que lorsque CustomControl est situé dans un formulaire dans le concepteur, ce CustomControl s'exécute en mode exécution.

J'ai constaté que la propriété DesignMode ne fonctionne correctement que dans Form.

9
Vaclav Svara

IMPORTANT

Il existe une différence entre Windows Formulaires ouWPF!!

Ils ont des concepteurs différents et ont besoin de contrôles différents . En outre, il est délicat de mélanger des contrôles Forms et WPF. (par exemple, des contrôles WPF dans une fenêtre de formulaire)

Si vous avez Windows Formulaires uniquement , utilisez ceci:

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);

Si vous avez WPF uniquement , utilisez cette vérification:

Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

Si vous avez un usage mixte de Forms et WPF, utilisez un chèque comme celui-ci:

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

if (isInWpfDesignerMode || isInFormsDesignerMode)
{
    // is in any designer mode
}
else
{
    // not in designer mode
}

Pour voir le mode actuel, vous pouvez afficher un MessageBox pour le débogage:

// show current mode
MessageBox.Show(String.Format("DESIGNER CHECK:  WPF = {0}   Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode));

Remarque:

Vous devez ajouter les espaces de noms System.ComponentModel et System.Diagnostics .

8
Beauty

Les contrôles (Forms, UserControls, etc.) héritent de Component class qui a bool property DesignMode so:

if(DesignMode)
{
  //If in design mode
}
6
formatc

Vous devez utiliser la propriété Component.DesignMode. Autant que je sache, cela ne devrait pas être utilisé par un constructeur.

5
Ula Krukar

Une autre méthode intéressante est décrite sur ce blog: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode -ou-usermode/

Fondamentalement, il teste l'assemblage d'exécution référencé statiquement à partir de l'entrée Assembly. Cela élimine la nécessité de suivre les noms des assemblées ('devenv.exe', 'monodevelop.exe' ..). 

Toutefois, cela ne fonctionne pas dans tous les autres scénarios, où l'assembly est chargé dynamiquement (VSTO en est un exemple).

4
user492238

Avec la coopération du concepteur ... Il peut être utilisé dans les contrôles, les composants, dans tous les lieux

    private bool getDesignMode()
    {
        IDesignerHost Host;
        if (Site != null)
        {
            Host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (Host != null)
            {
                if (Host.RootComponent.Site.DesignMode) MessageBox.Show("Design Mode");
                else MessageBox.Show("Runtime Mode");
                return Host.RootComponent.Site.DesignMode;
            }
        }
        MessageBox.Show("Runtime Mode");
        return false;
    }

Les lignes MessageBox.Show( doivent être supprimées. Cela ne fait que m'assurer que cela fonctionne correctement.

2
Vaclav Svara

C'est la méthode que j'ai utilisée dans mon projet:

//use a Property or Field for keeping the info to avoid runtime computation
public static bool NotInDesignMode { get; } = IsNotInDesignMode();
private static bool IsNotInDesignMode()
{
    /*
    File.WriteAllLines(@"D:\1.log", new[]
    {
        LicenseManager.UsageMode.ToString(), //not always reliable, e.g. WPF app in Blend this will return RunTime
        Process.GetCurrentProcess().ProcessName, //filename without extension
        Process.GetCurrentProcess().MainModule.FileName, //full path
        Process.GetCurrentProcess().MainModule.ModuleName, //filename
        Assembly.GetEntryAssembly()?.Location, //null for WinForms app in VS IDE
        Assembly.GetEntryAssembly()?.ToString(), //null for WinForms app in VS IDE
        Assembly.GetExecutingAssembly().Location, //always return your project's output Assembly info
        Assembly.GetExecutingAssembly().ToString(), //always return your project's output Assembly info
    });
    //*/

    //LicenseManager.UsageMode will return RunTime if LicenseManager.context is not present.
    //So you can not return true by judging it's value is RunTime.
    if (LicenseUsageMode.Designtime == LicenseManager.UsageMode) return false;
    var procName = Process.GetCurrentProcess().ProcessName.ToLower();
    return "devenv" != procName //WinForms app in VS IDE
        && "xdesproc" != procName //WPF app in VS IDE/Blend
        && "blend" != procName //WinForms app in Blend
        //other IDE's process name if you detected by log from above
        ;
}

Attention !!!: Le code retourné bool indiquePASen mode création!

1
qaqz111
    private void CtrlSearcher_Load(object sender, EventArgs e)
    {
           if(!this.DesignMode) InitCombos();
    }
1
Ángel Ibáñez

Vous pouvez utiliser ceci

if (DesignerProperties.GetIsInDesignMode(this))
{
...
}
0
Derek Tremblay

Si vous souhaitez exécuter certaines lignes lors de son exécution, mais pas dans le concepteur Visual Studio, vous devez implémenter la propriété DesignMode comme suit: 

// this code is in the Load of my UserControl
if (this.DesignMode == false)
{
    // This will only run in run time, not in the designer.
    this.getUserTypes();
    this.getWarehouses();
    this.getCompanies();
}
0
Giovanny Farto M.

La solution LicenseManager ne fonctionne pas dans OnPaint, pas plus que this.DesignMode. J'ai eu recours à la même solution que @Jarek.

Voici la version en cache:

    private static bool? isDesignMode;
    private static bool IsDesignMode()
    {
        if (isDesignMode == null)
            isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv"));

        return isDesignMode.Value;
    }

Sachez que cela échouera si vous utilisez un tiers IDE ou si Microsoft (ou votre utilisateur final) décide de changer le nom de l'exécutable du VS en un nom autre que "devenv". Le taux d'échec sera très faible. Assurez-vous de gérer les erreurs qui pourraient en résulter dans le code et qui échoueraient à la suite de cela, et tout ira bien pour vous.

0
Rob