Как определить, выполняется ли код .NET дизайнером Visual Studio - PullRequest
55 голосов
/ 16 сентября 2008

Я получаю некоторые ошибки в моем коде при открытии формы Windows Forms в конструкторе Visual Studio. Я хотел бы выполнить переход в моем коде и выполнить другую инициализацию, если форма открывается дизайнером, чем если бы она выполнялась по-настоящему.

Как я могу определить во время выполнения, выполняется ли код как часть дизайнера, открывающего форму?

Ответы [ 24 ]

49 голосов
/ 16 сентября 2008

Чтобы узнать, находитесь ли вы в «режиме разработки»:

  • Компоненты (и элементы управления) Windows Forms имеют свойство DesignMode .
  • Элементы управления Windows Presentation Foundation должны использовать присоединенное свойство IsInDesignMode .
47 голосов
/ 23 мая 2012
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}
19 голосов
/ 16 сентября 2008

Вероятно, вы ищете свойство Control.DesignMode. Он сообщает вам, если родительский элемент управления открыт в конструкторе.

В большинстве случаев это работает отлично, но есть случаи, когда это работает не так, как ожидалось. Во-первых, это не работает в конструкторе элементов управления. Во-вторых, DesignMode ложно для «внучатых» элементов управления. Например, DesignMode для элементов управления, размещенных в UserControl, вернет false, когда UserControl размещен в родительском элементе.

Есть довольно легкий обходной путь. Это выглядит примерно так:

public bool HostedDesignMode
{
  get 
  {
     Control parent = Parent;
     while (parent!=null)
     {
        if(parent.DesignMode) return true;
        parent = parent.Parent;
     }
     return DesignMode;
  }
}

Я не тестировал этот код, но он должен работать.

15 голосов
/ 09 декабря 2008

Самый надежный подход:

public bool isInDesignMode
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        bool res = process.ProcessName == "devenv";
        process.Dispose();
        return res;
    }
}
13 голосов
/ 18 октября 2011

Самый надежный способ сделать это - игнорировать свойство DesignMode и использовать свой собственный флаг, который устанавливается при запуске приложения.

Класс:

public static class Foo
{
    public static bool IsApplicationRunning { get; set; }
}

Program.cs:

[STAThread]
static void Main()
{
     Foo.IsApplicationRunning = true;
     // ... code goes here ...
}

Тогда просто проверьте флаг там, где он вам нужен.

if(Foo.IsApplicationRunning)
{
    // Do runtime stuff
}
else
{
    // Do design time stuff
}
5 голосов
/ 27 сентября 2012

Подход devenv перестал работать в VS2012, так как у дизайнера появился собственный процесс. Вот решение, которое я сейчас использую (часть 'devenv' оставлена ​​там для устаревшего, но без VS2010 я не могу это проверить) .

private static readonly string[] _designerProcessNames = new[] { "xdesproc", "devenv" };

private static bool? _runningFromVisualStudioDesigner = null;
public static bool RunningFromVisualStudioDesigner
{
  get
  {
    if (!_runningFromVisualStudioDesigner.HasValue)
    {
      using (System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess())
      {
        _runningFromVisualStudioDesigner = _designerProcessNames.Contains(currentProcess.ProcessName.ToLower().Trim());
      }
    }

    return _runningFromVisualStudioDesigner.Value;
  }
}
4 голосов
/ 10 февраля 2015

У меня была такая же проблема в Visual Studio Express 2013. Я попробовал многие из предложенных здесь решений, но одно из них, которое мне помогло, было ответом на другой поток , который я здесь повторю в случае, если ссылка не работает:

protected static bool IsInDesigner
{
    get { return (Assembly.GetEntryAssembly() == null); }
}
3 голосов
/ 01 апреля 2014
/// <summary>
/// Are we in design mode?
/// </summary>
/// <returns>True if in design mode</returns>
private bool IsDesignMode() {
    // Ugly hack, but it works in every version
    return 0 == String.CompareOrdinal(
        "devenv.exe", 0,
        Application.ExecutablePath, Application.ExecutablePath.Length - 10, 10);
}
3 голосов
/ 15 декабря 2012
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
    bool inDesigner = process.ProcessName.ToLower().Trim() == "devenv";
    return inDesigner;
}

Я попробовал приведенный выше код (добавил оператор using), и в некоторых случаях это не получалось. Тестирование в конструкторе пользовательского элемента управления, размещенного непосредственно в форме с загрузкой конструктора при запуске. Но будет работать в других местах.

Что сработало для меня, во всех местах:

private bool isDesignMode()
{
    bool bProcCheck = false;
    using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
    {
        bProcCheck = process.ProcessName.ToLower().Trim() == "devenv";
    }

    bool bModeCheck = (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime);

    return bProcCheck || DesignMode || bModeCheck;
}

Может быть, немного излишним, но это работает, так что для меня это достаточно.

Успехом в приведенном выше примере является bModeCheck, поэтому, вероятно, DesignMode является излишним.

2 голосов
/ 16 сентября 2008

Это хакерство, но если вы используете VB.NET и когда вы работаете из Visual Studio My.Application.Deployment.CurrentDeployment не будет ничего потому что вы еще не развернули его. Я не уверен, как проверить эквивалентное значение в C #.

...