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

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

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

Ответы [ 24 ]

1 голос
/ 14 июля 2012

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

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 знает, что я не хочу сериализовать это свойство, поэтому он может его пропустить. Он отображает только некоторые странные строки в окне свойств формы, но, кажется, их можно игнорировать.

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

1 голос
/ 24 июня 2012

При запуске проекта к его имени добавляется ".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;
        }
    }

У меня это работает.

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

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

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

Мы используем следующий код в 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;
    }
1 голос
/ 16 сентября 2008
System.ComponentModel.Component.DesignMode == true
1 голос
/ 16 сентября 2008

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

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

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

1 голос
/ 16 сентября 2008
System.Diagnostics.Debugger.IsAttached
0 голосов
/ 12 мая 2015

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

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

if (AppDomain.CurrentDomain.BaseDirectory.Contains(testString))
{
    //Your code here
}
0 голосов
/ 16 марта 2016

После тестирования большинства ответов здесь, к сожалению, у меня ничего не получилось (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();
}
0 голосов
/ 13 марта 2015

Вот еще один:

        //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 }
...