在开发控件时,是否有人找到针对DesignMode问题的有用解决方案?
问题是,如果嵌套控件,则DesignMode仅适用于第一级。第二和较低级别的DesignMode将始终返回FALSE。
标准的技巧是查看正在运行的进程的名称,如果它是“DevEnv.EXE”,那么它必须是studio,因此DesignMode确实为TRUE。
这样做的问题是寻找ProcessName会在注册表和其他奇怪的地方工作,最终结果是用户可能没有查看进程名称所需的权限。此外,这条奇怪的路线非常慢。因此,我们不得不堆积更多的骇客才能使用单例,并且如果在询问进程名称时抛出错误,则假定DesignMode为FALSE。
确定DesignMode的一种好方法是按顺序进行的。最终让Microsoft将其内部修复到框架中会更好!
最佳答案
回顾这个问题,我现在“发现”了5种不同的方法,如下所示:
System.ComponentModel.DesignMode property
System.ComponentModel.LicenseManager.UsageMode property
private string ServiceString()
{
if (GetService(typeof(System.ComponentModel.Design.IDesignerHost)) != null)
return "Present";
else
return "Not present";
}
public bool IsDesignerHosted
{
get
{
Control ctrl = this;
while(ctrl != null)
{
if((ctrl.Site != null) && ctrl.Site.DesignMode)
return true;
ctrl = ctrl.Parent;
}
return false;
}
}
public static bool IsInDesignMode()
{
return System.Reflection.Assembly.GetExecutingAssembly()
.Location.Contains("VisualStudio"))
}
为了尝试解决建议的三个解决方案,我创建了一个包含三个项目的小测试解决方案:
然后,我将SubSubControl嵌入SubControl中,然后将其中之一嵌入TestApp.Form中。
此屏幕快照显示了运行时的结果。
此屏幕快照显示了在Visual Studio中打开表单的结果:
结论:似乎没有经过反射(reflection),构造函数内唯一可靠的是LicenseUsage,而构造函数外唯一可靠的是'IsDesignedHosted'(通过下面的BlueRaja)
PS:请参阅下面ToolmakerSteve的评论(我尚未测试):“请注意,IsDesignerHosted的答案已更新为包括LicenseUsage ...,因此现在测试可以简单地是if(IsDesignerHosted)。另一种方法是test LicenseManager in constructor and cache the result。”