如何判断 Visual Studio 设计器是否正在运行 .NET 代码

发布于 2024-07-05 11:29:13 字数 143 浏览 8 评论 0原文

当我在 Visual Studio 的设计器中打开 Windows 窗体表单时,我的代码中出现一些错误。 如果设计者打开表单而不是实际运行表单,我想在我的代码中进行分支并执行不同的初始化。

如何在运行时确定代码是否作为设计器打开表单的一部分而执行?

I am getting some errors thrown in my code when I open a Windows Forms form in Visual Studio's designer. I would like to branch in my code and perform a different initialization if the form is being opened by designer than if it is being run for real.

How can I determine at run-time if the code is being executed as part of designer opening the form?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(25

后eg是否自 2024-07-12 11:29:15

最可靠的方法是:

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

The most reliable approach is:

public bool isInDesignMode
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        bool res = process.ProcessName == "devenv";
        process.Dispose();
        return res;
    }
}
撕心裂肺的伤痛 2024-07-12 11:29:15

Control.DesignMode 属性可能就是您正在寻找的。 它告诉您控件的父级是否在设计器中打开。

在大多数情况下,它工作得很好,但在某些情况下,它不能按预期工作。 首先,它在控件构造函数中不起作用。 其次,DesignMode 对于“孙子”控件为 false。 例如,当 UserControl 托管在父级中时,UserControl 中托管的控件的 DesignMode 将返回 false。

有一个非常简单的解决方法。 它是这样的:

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

我还没有测试该代码,但它应该工作。

The Control.DesignMode property is probably what you're looking for. It tells you if the control's parent is open in the designer.

In most cases it works great, but there are instances where it doesn't work as expected. First, it doesn't work in the controls constructor. Second, DesignMode is false for "grandchild" controls. For example, DesignMode on controls hosted in a UserControl will return false when the UserControl is hosted in a parent.

There is a pretty easy workaround. It goes something like this:

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

I haven't tested that code, but it should work.

半枫 2024-07-12 11:29:15

最可靠的方法是忽略 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
}

The most reliable way to do this is to ignore the DesignMode property and use your own flag that gets set on application startup.

Class:

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

Program.cs:

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

Then just check the flag whever you need it.

if(Foo.IsApplicationRunning)
{
    // Do runtime stuff
}
else
{
    // Do design time stuff
}
骄兵必败 2024-07-12 11:29:15

我在 Visual Studio Express 2013 中遇到了同样的问题。我尝试了此处建议的许多解决方案,但对我有用的解决方案是的答案另一个线程,我将在这里重复,以防链接损坏:

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

I had the same problem in Visual Studio Express 2013. I tried many of the solutions suggested here but the one that worked for me was an answer to a different thread, which I will repeat here in case the link is ever broken:

protected static bool IsInDesigner
{
    get { return (Assembly.GetEntryAssembly() == null); }
}
渔村楼浪 2024-07-12 11:29:15

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

The devenv approach stopped working in VS2012 as the designer now has its own process. Here is the solution I am currently using (the 'devenv' part is left there for legacy, but without VS2010 I am not able to test that though).

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;
  }
}
温柔戏命师 2024-07-12 11:29:15

您检查控件的 DesignMode 属性:

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

请注意,这在构造函数中不起作用,因为组件尚未初始化。

You check the DesignMode property of your control:

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

Note that this won't work in your constructor because the components haven't been initialized yet.

无尽的现实 2024-07-12 11:29: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;
    }

基本上上面的逻辑可以归结为:

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

We use the following code in UserControls and it does the work. Using only DesignMode will not work in your app that uses your custom user controls as pointed out by other members.

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

Basically the logic above boils down to:

    public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
    {
        if (ctrl == null) return false;
        if (ctrl.Site != null && ctrl.Site.DesignMode) return true;
        return IsControlDesignerHosted(ctrl.Parent);
    }
喜你已久 2024-07-12 11:29:15

这是 hack-ish,但如果您使用 VB.NET 并且当您'从 Visual Studio 中重新运行 My.Application.Deployment.CurrentDeployment 将会什么都没有,因为您还没有部署它。 我不确定如何检查 C# 中的等效值。

It's hack-ish, but if you're using VB.NET and when you're running from within Visual Studio My.Application.Deployment.CurrentDeployment will be Nothing, because you haven't deployed it yet. I'm not sure how to check the equivalent value in C#.

混浊又暗下来 2024-07-12 11:29:15
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 可能是多余的。

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

I tried the above code (added a using statement) and this would fail on some occasions for me. Testing in the constructor of a usercontrol placed directly in a form with the designer loading at startup. But would work in other places.

What worked for me, in all locations is:

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

Maybe a bit overkill, but it works, so is good enough for me.

The success in the example noted above is the bModeCheck, so probably the DesignMode is surplus.

何其悲哀 2024-07-12 11:29:15
System.Diagnostics.Debugger.IsAttached
System.Diagnostics.Debugger.IsAttached
星軌x 2024-07-12 11:29:15
/// <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);
}
/// <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);
}
冰葑 2024-07-12 11:29:15

我不确定在调试模式下运行是否算作真实的,但一个简单的方法是在代码中包含一个 if 语句来检查 System.Diagnostics.Debugger.IsAttached

I'm not sure if running in debug mode counts as real, but an easy way is to include an if statement in your code that checkes for System.Diagnostics.Debugger.IsAttached.

池予 2024-07-12 11:29:15

运行项目时,其名称会附加“.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;
        }
    }

它对我有用。

When running a project, its name is appended with ".vshost".

So, I use this:

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

It works for me.

东北女汉子 2024-07-12 11:29:15

为了解决这个问题,你还可以编写如下代码:

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

}

To solve the problem, you can also code as below:

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

}
往昔成烟 2024-07-12 11:29:15

这是另一个:

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

Here's another one:

        //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 }
疧_╮線 2024-07-12 11:29:15

在测试了这里的大部分答案后,不幸的是,没有任何对我有用的东西(VS2015)。
因此,我对 JohnV 的答案添加了一些改动,但它并不能开箱即用,因为 DesignMode 是受保护的属性在控制类中。

首先,我创建了一个扩展方法,它通过 Reflection 返回 DesignMode 的属性值:

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 的混乱,虽然不应该轻易使用反射,但在这个例子就完全不同了! ;)

编辑:

您还可以将第二个函数设置为扩展方法,如下所示:

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

After testing most of the answers here, unfortunately nothing worked for me (VS2015).
So I added a little twist to JohnV's answer, which didn't work out of the box, since DesignMode is a protected Property in the Control class.

First I made an extension method which returns the DesignMode's Property value via 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);
}

and then I made a function like JohnV:

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

This is the only method that worked for me, avoiding all the ProcessName mess, and while reflection should not be used lightly, in this case it did all the difference! ;)

EDIT:

You can also make the second function an extension method like this:

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();
}
双马尾 2024-07-12 11:29:15

如果您在窗体或控件中,则可以使用 DesignMode 属性:

if (DesignMode)
{
        DesignMode Only stuff
}

If you are in a form or control you can use the DesignMode property:

if (DesignMode)
{
        DesignMode Only stuff
}
抠脚大汉 2024-07-12 11:29:15

我发现 DesignMode 属性有问题,至少在以前版本的 Visual Studio 中是这样。 因此,我使用以下逻辑制作了自己的:

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

我知道,这有点黑客,但效果很好。

I found the DesignMode property to be buggy, at least in previous versions of Visual Studio. Hence, I made my own using the following logic:

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

Kind of a hack, I know, but it works well.

み格子的夏天 2024-07-12 11:29:15
System.ComponentModel.Component.DesignMode == true
System.ComponentModel.Component.DesignMode == true
人海汹涌 2024-07-12 11:29:15

如果您在设计时创建了根本不需要的属性,则可以使用 DesignerSerializationVisibility 属性并将其设置为隐藏。 例如:

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

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

每次我使用 NotImplementedException() 更改表单并尝试保存时,它都会阻止我的 Visual Studio 崩溃。 相反,Visual Studio 知道我不想序列化此属性,因此它可以跳过它。 它只在表单的属性框中显示一些奇怪的字符串,但似乎可以安全地忽略。

请注意,此更改在您重建后才会生效。

If you created a property that you don't need at all at design time, you can use the DesignerSerializationVisibility attribute and set it to Hidden. For example:

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

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

It stopped my Visual Studio crashing every time I made a change to the form with NotImplementedException() and tried to save. Instead, Visual Studio knows that I don't want to serialize this property, so it can skip it. It only displays some weird string in the properties box of the form, but it seems to be safe to ignore.

Please note that this change does not take effect until you rebuild.

霊感 2024-07-12 11:29:15

对于 WPF(希望这对那些偶然发现这个问题的 WPF 人员有用):

if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
}

GetIsInDesignMode 需要一个 DependencyObject。 如果您没有,只需创建一个。

For WPF (hopefully this is useful for those WPF people stumbling upon this question):

if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(new DependencyObject()))
{
}

GetIsInDesignMode requires a DependencyObject. If you don't have one, just create one.

薄暮涼年 2024-07-12 11:29:15
    /// <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");
        }
    }
    /// <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");
        }
    }
被你宠の有点坏 2024-07-12 11:29:15

这是一种灵活的方法,可以适应您的编译位置以及您是否关心所处的模式。

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

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

Here's a flexible way that is adaptable to where you compile from as well as whether or not you care which mode you're in.

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

if (AppDomain.CurrentDomain.BaseDirectory.Contains(testString))
{
    //Your code here
}
一笑百媚生 2024-07-12 11:29:14

要了解您是否处于“设计模式”:

  • Windows 窗体组件(和控件)具有 DesignMode 属性。
  • Windows Presentation Foundation 控件应使用附加的 IsInDesignMode财产。

To find out if you're in "design mode":

  • Windows Forms components (and controls) have a DesignMode property.
  • Windows Presentation Foundation controls should use the IsInDesignMode attached property.
静水深流 2024-07-12 11:29:13
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文