Подтвердить что ты не робот

Обнаружение режима проектирования из конструктора Control

Следуя этому вопросу, можно ли определить, находится ли в дизайне или режиме выполнения внутри конструктора объекта?

Я понимаю, что это может быть невозможно, и что мне придется изменить то, что я хочу, но на данный момент меня интересует этот конкретный вопрос.

4b9b3361

Ответ 1

Вы можете использовать перечисление LicenceUsageMode в пространстве имен System.ComponentModel:

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

Ответ 2

Вы ищете что-то вроде этого:

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

Вы также можете сделать это, проверив имя процесса:

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

Ответ 3

Компонент... насколько мне известно, не имеет свойства DesignMode. Это свойство предоставляется Control. Но проблема в том, что CustomControl находится в форме в конструкторе, этот CustomControl работает в режиме исполнения.

Я испытал, что свойство DesignMode работает корректно только в форме.

Ответ 4

ВАЖНО

Существует разница в использовании Windows Формы или WPF!!

У них разные дизайнеры и нужны разные проверки. Кроме того, это сложно, когда вы смешиваете элементы управления Forms и WPF. (например, WPF контролирует внутри окна Forms)

Если у вас Windows Только формы, используйте это:

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

Если у вас только WPF, используйте эту проверку:

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

Если у вас смешанное использование форм и WPF, используйте проверку, например:

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
}

Чтобы увидеть текущий режим, вы можете показать MessageBox для отладки:

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

Примечание:

Вам нужно добавить пространства имен System.ComponentModel и System.Diagnostics.

Ответ 5

Вы должны использовать свойство Component.DesignMode. Насколько я знаю, это не должно использоваться из конструктора.

Ответ 6

В этом блоге описан еще один интересный метод: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or-usermode/

В основном, он проверяет, что исполняющая сборка статически ссылается на сборку. Это обходит необходимость отслеживать имена сборок ('devenv.exe', 'monodevelop.exe'..).

Однако он не работает во всех других сценариях, где сборка динамически загружается (VSTO является одним из примеров).

Ответ 7

Элементы управления (Forms, UserControls и т.д.) наследуют Component class, который имеет bool property DesignMode так:

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

Ответ 8

В сотрудничестве с дизайнером... Он может использоваться в элементах управления, компонентов, во всех местах

    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;
    }
Строки

MessageBox.Show( должны быть удалены. Это только делает меня уверенным, что он работает правильно.

Ответ 9

Решение LicenseManager не работает внутри OnPaint, и это does.DesignMode. Я прибегал к тому же решению, что и @Jarek.

Здесь кешированная версия:

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

        return isDesignMode.Value;
    }

Помните, что это произойдет, если вы используете стороннюю среду IDE или если Microsoft (или ваш конечный пользователь) решит изменить имя исполняемого файла VS на что-то другое, кроме "devenv". Частота отказов будет очень низкой, просто убедитесь, что вы справляетесь с любыми возникающими ошибками, которые могут возникнуть в коде, который не работает в результате этого, и все будет в порядке.

Ответ 10

Если вы хотите запускать некоторые строки при запуске, но не в дизайнере Visual Studio, вы должны реализовать свойство DesignMode следующим образом:

// 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();
}

Ответ 11

Это метод, который я использовал в своем проекте:

//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 output assembly info
        Assembly.GetExecutingAssembly().ToString(), //always return your project output assembly info
    });
    //*/

    //LicenseManager.UsageMode will return RunTime if LicenseManager.context is not present.
    //So you can not return true by judging it 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 process name if you detected by log from above
        ;
}

Внимание !!!: Возвращенный код bool указывает NOT в режиме разработки!

Ответ 12

    private void CtrlSearcher_Load(object sender, EventArgs e)
    {
           if(!this.DesignMode) InitCombos();
    }