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

Как определить, выполняется ли .NET-код дизайнером Visual Studio

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

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

4b9b3361

Ответ 1

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

  • Компоненты Windows Forms (и элементы управления) имеют свойство DesignMode.
  • Элементы управления Windows Presentation Foundation должны использовать прикрепленное свойство IsInDesignMode.

Ответ 2

if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}

Ответ 3

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

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

Существует довольно простое решение. Это происходит примерно так:

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

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

Ответ 4

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

public bool isInDesignMode
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        bool res = process.ProcessName == "devenv";
        process.Dispose();
        return res;
    }
}

Ответ 5

Самый надежный способ сделать это - игнорировать свойство 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
}

Ответ 6

Подход 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;
  }
}

Ответ 7

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

protected static bool IsInDesigner
{
    get { return (Assembly.GetEntryAssembly() == null); }
}

Ответ 8

using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
    bool inDesigner = process.ProcessName.ToLower().Trim() == "devenv";
    return inDesigner;
}

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

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

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 является излишним.

Ответ 9

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

Ответ 10

System.Diagnostics.Debugger.IsAttached

Ответ 11

Я не уверен, что работа в режиме отладки считается реальной, но простой способ - включить в свой код инструкцию if, которая проверяет System.Diagnostics.Debugger.IsAttached.

Ответ 12

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

Ответ 13

Вы проверяете свойство DesignMode вашего элемента управления:

if (!DesignMode)
{
//Do production runtime stuff
}

Обратите внимание, что это не будет работать в вашем конструкторе, потому что компоненты еще не инициализированы.

Ответ 14

System.ComponentModel.Component.DesignMode == true

Ответ 15

Мы используем следующий код в UserControls, и он выполняет эту работу. Использование только DesignMode не будет работать в вашем приложении, которое использует ваши пользовательские элементы управления, как указано другими членами.

    public bool IsDesignerHosted
    {
        get { return IsControlDesignerHosted(this); }
    }

    public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
    {
        if (ctrl != null)
        {
            if (ctrl.Site != null)
            {
                if (ctrl.Site.DesignMode == true)
                    return true;
                else
                {
                    if (IsControlDesignerHosted(ctrl.Parent))
                        return true;
                    else
                        return false;
                }
            }
            else
            {
                if (IsControlDesignerHosted(ctrl.Parent))
                    return true;
                else
                    return false;
            }
        }
        else
            return false;
    }

Ответ 16

При запуске проекта его имя добавляется с помощью ".vshost".

Итак, я использую это:

    public bool IsInDesignMode
    {
        get
        {
            Process p = Process.GetCurrentProcess();
            bool result = false;

            if (p.ProcessName.ToLower().Trim().IndexOf("vshost") != -1)
                result = true;
            p.Dispose();

            return result;
        }
    }

Это работает для меня.

Ответ 17

Если вы создали свойство, которое вам вообще не нужно во время разработки, вы можете использовать атрибут DesignerSerializationVisibility и установить его в Hidden. Например:

protected virtual DataGridView GetGrid()
{
    throw new NotImplementedException("frmBase.GetGrid()");
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ColumnCount { get { return GetGrid().Columns.Count; } set { /*Some code*/ } }

Это остановило мою работу в Visual Studio каждый раз, когда я внес изменения в форму с помощью NotImplementedException() и попытался сохранить. Вместо этого Visual Studio знает, что я не хочу сериализовать это свойство, поэтому он может пропустить его. Он отображает только некоторую странную строку в окне свойств формы, но, похоже, ее можно игнорировать.

Обратите внимание, что это изменение не вступает в силу до восстановления.

Ответ 18

Если вы находитесь в форме или управлении, вы можете использовать свойство DesignMode:

if (DesignMode)
{
        DesignMode Only stuff
}

Ответ 19

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

Process.GetCurrentProcess().ProcessName.ToLower().Trim() == "devenv";

Вид хака, я знаю, но он работает хорошо.

Ответ 20

Чтобы решить эту проблему, вы также можете ввести код, как показано ниже:

private bool IsUnderDevelopment
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        if (process.ProcessName.EndsWith(".vshost")) return true;
        else return false;
    }

}

Ответ 21

Здесь еще один:

        //Caters only to thing done while only in design mode
        if (App.Current.MainWindow == null){ // in design mode  }

        //Avoids design mode problems
        if (App.Current.MainWindow != null) { //applicaiton is running }

Ответ 22

После тестирования большинства ответов здесь, к сожалению, ничего не работало для меня (VS2015). Поэтому я добавил немного поворота в ответ JohnV, который не работал из коробки, поскольку DesignMode является защищенным свойством в классе Control.

Сначала я сделал метод расширения, который возвращает значение свойства DesignMode через Reflection:

public static Boolean GetDesignMode(this Control control)
{
    BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
    PropertyInfo prop = control.GetType().GetProperty("DesignMode", bindFlags);
    return (Boolean)prop.GetValue(control, null);
}

а затем я сделал такую ​​функцию, как JohnV:

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

Это единственный метод, который работал у меня, избегая всех беспорядков ProcessName, и в то время как отражение не следует использовать легкомысленно, в этом случае все это имело значение!;)

EDIT:

Вы также можете сделать вторую функцию методом расширения следующим образом:

public static Boolean IsInDesignMode(this Control control)
{
    Control parent = control.Parent;
    while (parent != null)
    {
        if (parent.GetDesignMode())
        {
            return true;
        }
        parent = parent.Parent;
    }
    return control.GetDesignMode();
}

Ответ 23

    /// <summary>
    ///  Whether or not we are being run from the Visual Studio IDE
    /// </summary>
    public bool InIDE
    {
        get
        {
            return Process.GetCurrentProcess().ProcessName.ToLower().Trim().EndsWith("vshost");
        }
    }

Ответ 24

Здесь гибкий способ, который можно адаптировать к тому, где вы компилируете, а также независимо от того, заботите ли вы, в каком режиме вы находитесь.

string testString1 = "\\bin\\";
//string testString = "\\bin\\Debug\\";
//string testString = "\\bin\\Release\\";

if (AppDomain.CurrentDomain.BaseDirectory.Contains(testString))
{
    //Your code here
}