题
有人发现了一个有用的解决方案的DesignMode问题时发展中控制?
问题是,如果你窝的控制,然后DesignMode仅适用于第一级。第二和较低的水平DesignMode将总回报是假的。
标准的黑客已经看名称的运行的进程,并如果它是"DevEnv.EXE"那么就必须studio因此DesignMode是真的。
问题是寻找进程名工作的其周围的方式通过注册和其他奇怪的部分的最终结果的用户可能不具备必要的权利这一进程名称。另外这个奇怪的路线,是非常缓慢。因此,我们必须桩额外的黑客使用一个单独的并且如果错误是抛的时候要求进程名称,然后假设DesignMode是错误的。
一个漂亮整洁的方式来确定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(它应用程序),
- SubControl(dll)
- SubSubControl(dll)
我然后嵌入式的SubSubControl在SubControl,然后每一个在TestApp.形式。
这个图显示了在运行。
这个图显示了对结果的形式开Visual Studio:
结论:它会出现 没有反射 唯一一个可靠的 内 构造是LicenseUsage,只有一个是可靠的 外面 构造是'IsDesignedHosted'(通过 BlueRaja 下面)
PS:见ToolmakerSteve的评论如下(我没有测试):"注意 IsDesignerHosted 答案已经更新,包括LicenseUsage...,所以现在试验可以简单地是,如果(IsDesignerHosted).一种替代办法是 测试的许可证管理器在构造和缓的结果."
其他提示
从 这页:
([编辑2013年] 编辑工作的构造,使用的方法提供@hopla)
/// <summary>
/// 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 )
/// </summary>
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;
}
}
我已经提交 一个错误报告 与微软;我怀疑它会去任何地方,但投票,它不管怎么说,因为这显然是一个错误(不论是或不是 "通过设计").
你为什么不检查许可证管理器。UsageMode.该财产可以有所值LicenseUsageMode.运行时或LicenseUsageMode.设计时.
是你想码只运行在运行时,使用下列代码:
if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
{
bla bla bla...
}
这是方法,我利用内部的形式:
/// <summary>
/// Gets a value indicating whether this instance is in design mode.
/// </summary>
/// <value>
/// <c>true</c> if this instance is in design mode; otherwise, <c>false</c>.
/// </value>
protected bool IsDesignMode
{
get { return DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime; }
}
这种方式,结果将是正确的,即如果DesignMode或许可证管理器性能失败。
我们使用这个代码的成功:
public static bool IsRealDesignerMode(this Control c)
{
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
return true;
else
{
Control ctrl = c;
while (ctrl != null)
{
if (ctrl.Site != null && ctrl.Site.DesignMode)
return true;
ctrl = ctrl.Parent;
}
return System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
}
}
我的建议是一个优化的@blueraja-丹尼-pflughoeft 回复.这个解决方案不会计算结果每时间,但只有在第一时间(一个目无法更改UsageMode从设计运行时)
private bool? m_IsDesignerHosted = null; //contains information about design mode state
/// <summary>
/// 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 https://stackoverflow.com/a/2693338/238419 )
/// </summary>
[Browsable(false)]
public bool IsDesignerHosted
{
get
{
if (m_IsDesignerHosted.HasValue)
return m_IsDesignerHosted.Value;
else
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
m_IsDesignerHosted = true;
return true;
}
Control ctrl = this;
while (ctrl != null)
{
if ((ctrl.Site != null) && ctrl.Site.DesignMode)
{
m_IsDesignerHosted = true;
return true;
}
ctrl = ctrl.Parent;
}
m_IsDesignerHosted = false;
return false;
}
}
}
我用的许可证管理器的方法,但是高速缓存的价值从该构造中使用的整个生命周期中的实例。
public MyUserControl()
{
InitializeComponent();
m_IsInDesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
}
private bool m_IsInDesignMode = true;
public bool IsInDesignMode { get { return m_IsInDesignMode; } }
VB版本:
Sub New()
InitializeComponent()
m_IsInDesignMode = (LicenseManager.UsageMode = LicenseUsageMode.Designtime)
End Sub
Private ReadOnly m_IsInDesignMode As Boolean = True
Public ReadOnly Property IsInDesignMode As Boolean
Get
Return m_IsInDesignMode
End Get
End Property
我从来没有抓到这个了我自己,但你就不能走回父链的控制要看如果DesignMode设置任何地方上你吗?
由于没有一个方法是可靠的(DesignMode,许可证管理器)或有效率(过程中,递检查)我用一个 public static bool Runtime { get; private set }
在计划的水平,并明确设定它内部的主要()方法。
DesignMode是私人财产(从什么我可以告诉).答案是提供一种公共财产的公开DesignMode的支柱。然后你可以cascasde份链的用户控制,直到你遇到了一个非用户的控制或控制,是在设计模式。像这样的东西。...
public bool RealDesignMode()
{
if (Parent is MyBaseUserControl)
{
return (DesignMode ? true : (MyBaseUserControl) Parent.RealDesignMode;
}
return DesignMode;
}
在那里所有的UserControls继承MyBaseUserControl.或者你可以实现一个接口,公开"RealDeisgnMode".
请注意这种代码不是生活代码,只是袖口沉思.:)
我没有意识到你不能打电话给父母。DesignMode(和我学到了一些有关'保护'C#太...)
这是反射性的版本:(我怀疑可能有一个绩效优势,以使designModeProperty一个静态的领域)
static bool IsDesignMode(Control control)
{
PropertyInfo designModeProperty = typeof(Component).
GetProperty("DesignMode", BindingFlags.Instance | BindingFlags.NonPublic);
while (designModeProperty != null && control != null)
{
if((bool)designModeProperty.GetValue(control, null))
{
return true;
}
control = control.Parent;
}
return false;
}
我要打这个问题最近在Visual Studio2017年时,使用套UserControls.我相结合的若干做法提到的上述和其他地方,然后调整的代码,直到我有一个体面的扩展其工作方法可以接受的这么远。它执行一系列的检查、储存的导致静布尔变量以便使每一个检查是仅执行最多只有一旦在运行时间。该过程可能被矫枉过正,但这是保留的代码,从执行在工作室。希望这可以帮助别人。
public static class DesignTimeHelper
{
private static bool? _isAssemblyVisualStudio;
private static bool? _isLicenseDesignTime;
private static bool? _isProcessDevEnv;
private static bool? _mIsDesignerHosted;
/// <summary>
/// Property <see cref="Form.DesignMode"/> does not correctly report if a nested <see cref="UserControl"/>
/// is in design mode. InDesignMode is a corrected that property which .
/// (see https://connect.microsoft.com/VisualStudio/feedback/details/553305
/// and https://stackoverflow.com/a/2693338/238419 )
/// </summary>
public static bool InDesignMode(
this Control userControl,
string source = null)
=> IsLicenseDesignTime
|| IsProcessDevEnv
|| IsExecutingAssemblyVisualStudio
|| IsDesignerHosted(userControl);
private static bool IsExecutingAssemblyVisualStudio
=> _isAssemblyVisualStudio
?? (_isAssemblyVisualStudio = Assembly
.GetExecutingAssembly()
.Location.Contains(value: "VisualStudio"))
.Value;
private static bool IsLicenseDesignTime
=> _isLicenseDesignTime
?? (_isLicenseDesignTime = LicenseManager.UsageMode == LicenseUsageMode.Designtime)
.Value;
private static bool IsDesignerHosted(
Control control)
{
if (_mIsDesignerHosted.HasValue)
return _mIsDesignerHosted.Value;
while (control != null)
{
if (control.Site?.DesignMode == true)
{
_mIsDesignerHosted = true;
return true;
}
control = control.Parent;
}
_mIsDesignerHosted = false;
return false;
}
private static bool IsProcessDevEnv
=> _isProcessDevEnv
?? (_isProcessDevEnv = Process.GetCurrentProcess()
.ProcessName == "devenv")
.Value;
}