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

Zvi*_*Zvi 55 gui-designer visual-studio

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

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

Rog*_*mbe 49

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

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

  • DesignMode不是100%可靠. (41认同)
  • 有关可行的解决方案,请参阅NET3的答案.没有对JohnV意图的不尊重. (3认同)

NET*_*ET3 48

if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}
Run Code Online (Sandbox Code Playgroud)

  • +1.或者,LicenseUsageMode.Runtime,用于任何只应在运行时运行的内容. (3认同)
  • +1 这对我来说是一种享受。一直在使用 DesignMode,结果证明完全不可靠。将所有用法切换到此“UsageMode”替代方案。 (2认同)
  • 在 Visual Studio 2017 中,这适用于控件的构造函数,但不适用于控件的加载事件处理程序;在那里,它总是设置为运行时 <sigh> 当然不难解决(只需在构造函数中设置一个成员变量),但只是......很奇怪。 (2认同)

Joh*_*hnV 19

Control.DesignMode属性可能就是您要查找的内容.它告诉您控件的父级是否在设计器中打开.

在大多数情况下,它运行良好,但有些情况下它不能按预期工作.首先,它在控件构造函数中不起作用.其次,DesignMode对于"孙子"控件是错误的.例如,当UserControl托管在父对象中时,UserControl中托管的控件上的DesignMode将返回false.

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

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

我没有测试过该代码,但它应该可以工作.

  • 它不起作用DesignMode受到保护.但你提到的问题正是我得到的.但是如果把代码放在OnLoad()而不是.cor()中我也会得到它 (5认同)

GWL*_*osa 15

最可靠的方法是:

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

  • 虽然这是一个非常合理的解决方案,并且可能非常可靠,但是这个答案会让我感到震惊. (4认同)
  • 如果您使用“process.ProcessName.Contains("vshost")”作为条件,这也可用于确定您是否在 IDE 调试器中运行。 (2认同)
  • 修订版VS2013:由于XAML编辑器最终得到了自己的进程,你需要检查"XDesProc" (2认同)
  • ...除非您自己的应用程序的进程名称称为“devenv”(我想可能还有更多例外情况)。我不会将“最可靠的方法”称为具有明显缺陷的方法。呃,用户可能会将文件名更改为 devenv.exe,您的应用程序将突然停止正常工作。 (2认同)

Mar*_*ill 13

最可靠的方法是忽略DesignMode属性并使用在应用程序启动时设置的自己的标志.

类:

public static class Foo
{
    public static bool IsApplicationRunning { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Program.cs中:

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

然后只需检查您需要的标志.

if(Foo.IsApplicationRunning)
{
    // Do runtime stuff
}
else
{
    // Do design time stuff
}
Run Code Online (Sandbox Code Playgroud)

  • 我花了很多时间尝试不同的解决方案,但最终我也想出了设置一个标志的想法。这是唯一 100% 有效的方法。 (2认同)
  • 这对代码库不起作用,然后必须包含在对所有需要它的方法的调用中. (2认同)

Gee*_*eeC 6

我在 Visual Studio Express 2013 中遇到了同样的问题。我尝试了这里建议的许多解决方案,但对我有用的解决方案是对不同线程的回答,如果链接断开,我将在此处重复:

protected static bool IsInDesigner
{
    get { return (Assembly.GetEntryAssembly() == null); }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*dal 5

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;
  }
}
Run Code Online (Sandbox Code Playgroud)