有没有人在开发控件时找到了解决DesignMode问题的有用方法?
问题是,如果嵌套控件,则DesignMode仅适用于第一级.第二级和更低级别的DesignMode将始终返回FALSE.
标准的hack一直在查看正在运行的进程的名称,如果它是"DevEnv.EXE"那么它必须是studio,因此DesignMode真的是真的.
问题是寻找ProcessName通过注册表和其他奇怪的部分工作,最终结果是用户可能没有查看进程名称所需的权限.另外这条奇怪的路线很慢.所以我们不得不堆积额外的黑客来使用单例,如果在请求进程名称时抛出错误,则假设DesignMode为FALSE.
确定DesignMode的一个很好的干净方法是有序的.让微软在框架内部修复它会更好!
重新审视这个问题,我现在已经'发现'了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")) }
为了试图抓住提出的三个解决方案,我创建了一个小测试解决方案 - 有三个项目:
TestApp(winforms应用程序),
SubControl(dll)
SubSubControl(dll)
然后我将SubSubControl嵌入SubControl中,然后将其中一个嵌入TestApp.Form中.
此屏幕截图显示运行时的结果.
此屏幕截图显示了在Visual Studio中打开表单的结果:
结论:如果没有反射,在构造函数中唯一可靠的是LicenseUsage,并且在构造函数之外唯一可靠的是'IsDesignedHosted'(由BlueRaja在下面)
PS:请参阅下面的ToolmakerSteve评论(我还没有测试过):"请注意,IsDesignerHosted答案已更新为包含LicenseUsage ...,所以现在测试可以简单地为if(IsDesignerHosted).另一种方法是在构造函数中测试 LicenseManager 并缓存结果."
从这个页面:
([编辑2013]使用@hopla提供的方法编辑在构造函数中工作)
////// The DesignMode property does not correctly tell you if /// you are in design mode. IsDesignerHosted is a corrected /// version of that property. /// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305 /// and http://stackoverflow.com/a/2693338/238419 ) /// public bool IsDesignerHosted { get { if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) return true; Control ctrl = this; while (ctrl != null) { if ((ctrl.Site != null) && ctrl.Site.DesignMode) return true; ctrl = ctrl.Parent; } return false; } }
我已经向微软提交了一份错误报告 ; 我怀疑它会去任何地方,但无论如何都要投票,因为这显然是一个错误(无论它是否是"按设计").
为什么不检查LicenseManager.UsageMode.此属性的值可以是LicenseUsageMode.Runtime或LicenseUsageMode.Designtime.
您是否希望代码仅在运行时运行,请使用以下代码:
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime) { bla bla bla... }
这是我在表单中使用的方法:
////// Gets a value indicating whether this instance is in design mode. /// ////// protected bool IsDesignMode { get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; } }true if this instance is in design mode; otherwise,false . ///
这样,即使DesignMode或LicenseManager属性中的任何一个失败,结果也是正确的.