如何判断 Visual Studio 设计器是否正在运行 .NET 代码
当我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(25)
最可靠的方法是:
The most reliable approach is:
Control.DesignMode 属性可能就是您正在寻找的。 它告诉您控件的父级是否在设计器中打开。
在大多数情况下,它工作得很好,但在某些情况下,它不能按预期工作。 首先,它在控件构造函数中不起作用。 其次,DesignMode 对于“孙子”控件为 false。 例如,当 UserControl 托管在父级中时,UserControl 中托管的控件的 DesignMode 将返回 false。
有一个非常简单的解决方法。 它是这样的:
我还没有测试该代码,但它应该工作。
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:
I haven't tested that code, but it should work.
最可靠的方法是忽略 DesignMode 属性并使用在应用程序启动时设置的您自己的标志。
类:
Program.cs:
然后只需在需要的地方检查该标志即可。
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:
Program.cs:
Then just check the flag whever you need it.
我在 Visual Studio Express 2013 中遇到了同样的问题。我尝试了此处建议的许多解决方案,但对我有用的解决方案是的答案另一个线程,我将在这里重复,以防链接损坏:
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:
devenv 方法在 VS2012 中停止工作,因为设计器现在有了自己的流程。 这是我当前使用的解决方案(“devenv”部分保留在那里,但如果没有 VS2010,我无法测试它)。
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).
您检查控件的
DesignMode
属性:请注意,这在构造函数中不起作用,因为组件尚未初始化。
You check the
DesignMode
property of your control:Note that this won't work in your constructor because the components haven't been initialized yet.
我们在 UserControls 中使用以下代码,它就完成了工作。 正如其他成员所指出的,仅使用 DesignMode 将无法在使用自定义用户控件的应用程序中工作。
基本上上面的逻辑可以归结为:
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.
Basically the logic above boils down to:
这是 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#.
我尝试了上面的代码(添加了一个 using 语句),但在某些情况下这对我来说会失败。 在直接放置在表单中的用户控件的构造函数中进行测试,设计器在启动时加载。 但会在其他地方工作。
在所有地方对我来说都有效的是:
也许有点矫枉过正,但它有效,所以对我来说已经足够好了。
上面提到的示例中的成功是 bModeCheck,因此 DesignMode 可能是多余的。
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:
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.
我不确定在调试模式下运行是否算作真实的,但一个简单的方法是在代码中包含一个
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 forSystem.Diagnostics.Debugger.IsAttached
.运行项目时,其名称会附加“.vshost”。
所以,我用这个:
它对我有用。
When running a project, its name is appended with ".vshost".
So, I use this:
It works for me.
为了解决这个问题,你还可以编写如下代码:
To solve the problem, you can also code as below:
这是另一个:
Here's another one:
在测试了这里的大部分答案后,不幸的是,没有任何对我有用的东西(VS2015)。
因此,我对 JohnV 的答案添加了一些改动,但它并不能开箱即用,因为 DesignMode 是受保护的属性在控制类中。
首先,我创建了一个扩展方法,它通过 Reflection 返回 DesignMode 的属性值:
然后我创建了一个像 JohnV 这样的函数:
这是唯一对我有用的方法,避免了所有 ProcessName 的混乱,虽然不应该轻易使用反射,但在这个例子就完全不同了! ;)
编辑:
您还可以将第二个函数设置为扩展方法,如下所示:
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:
and then I made a function like JohnV:
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:
如果您在窗体或控件中,则可以使用 DesignMode 属性:
If you are in a form or control you can use the DesignMode property:
我发现 DesignMode 属性有问题,至少在以前版本的 Visual Studio 中是这样。 因此,我使用以下逻辑制作了自己的:
我知道,这有点黑客,但效果很好。
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:
Kind of a hack, I know, but it works well.
如果您在设计时创建了根本不需要的属性,则可以使用 DesignerSerializationVisibility 属性并将其设置为隐藏。 例如:
每次我使用
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:
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.
对于 WPF(希望这对那些偶然发现这个问题的 WPF 人员有用):
GetIsInDesignMode
需要一个 DependencyObject。 如果您没有,只需创建一个。For WPF (hopefully this is useful for those WPF people stumbling upon this question):
GetIsInDesignMode
requires a DependencyObject. If you don't have one, just create one.这是一种灵活的方法,可以适应您的编译位置以及您是否关心所处的模式。
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.
要了解您是否处于“设计模式”:
To find out if you're in "design mode":