具有嵌套控件的DesignMode

Joh*_*yer 86 .net user-controls

有没有人在开发控件时找到了解决DesignMode问题的有用方法?

问题是,如果嵌套控件,则DesignMode仅适用于第一级.第二级和更低级别的DesignMode将始终返回FALSE.

标准的hack一直在查看正在运行的进程的名称,如果它是"DevEnv.EXE"那么它必须是studio,因此DesignMode真的是真的.

问题是寻找ProcessName通过注册表和其他奇怪的部分工作,最终结果是用户可能没有查看进程名称所需的权限.另外这条奇怪的路线很慢.所以我们不得不堆积额外的黑客来使用单例,如果在请求进程名称时抛出错误,则假设DesignMode为FALSE.

确定DesignMode的一个很好的干净方法是有序的.让微软在框架内部修复它会更好!

Ben*_*jol 77

重新审视这个问题,我现在已经'发现'了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"))
}
Run Code Online (Sandbox Code Playgroud)

为了试图抓住提出的三个解决方案,我创建了一个小测试解决方案 - 有三个项目:

  • TestApp(winforms应用程序),
  • SubControl(dll)
  • SubSubControl(dll)

然后我将SubSubControl嵌入SubControl中,然后将其中一个嵌入TestApp.Form中.

此屏幕截图显示运行时的结果. 运行截图

此屏幕截图显示了在Visual Studio中打开表单的结果:

没有运行的屏幕截图

结论:如果没有反射,构造函数中唯一可靠的是LicenseUsage,并且在构造函数之外唯一可靠的是'IsDesignedHosted'(由BlueRaja在下面)

PS:请参阅下面的ToolmakerSteve评论(我还没有测试过):"请注意,IsDesignerHosted答案已更新为包含LicenseUsage ...,所以现在测试可以简单地为if(IsDesignerHosted).另一种方法是在构造函数中测试 LicenseManager 并缓存结果."

  • 所以,没有反射`if(LicenseUseage == LicenseUsageMode.Designtime || IsDesignerHosted)`将是100%正确的方法? (2认同)
  • 2021 年,Visual Studio2019 16.8 仍然有用! (2认同)

Blu*_*eft 31

这个页面:

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

我已经向微软提交了一份错误报告 ; 我怀疑它会去任何地方,但无论如何都要投票,因为这显然是一个错误(无论它是否是"按设计").


hop*_*pla 29

为什么不检查LicenseManager.UsageMode.此属性的值可以是LicenseUsageMode.Runtime或LicenseUsageMode.Designtime.

您是否希望代码仅在运行时运行,请使用以下代码:

if (LicenseManager.UsageMode == LicenseUsageMode.Runtime)
{
  bla bla bla...
}
Run Code Online (Sandbox Code Playgroud)

  • +1我也用过这个.让人兴奋的是,DesignMode不能在构造函数中工作. (8认同)

hus*_*ayt 7

这是我在表单中使用的方法:

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

这样,即使DesignMode或LicenseManager属性中的任何一个失败,结果也是正确的.


Jon*_*han 5

我使用 LicenseManager 方法,但缓存构造函数中的值以在实例的整个生命周期中使用。

public MyUserControl()
{
    InitializeComponent();
    m_IsInDesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
}

private bool m_IsInDesignMode = true;
public bool IsInDesignMode { get { return m_IsInDesignMode; } }
Run Code Online (Sandbox Code Playgroud)

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