在开发控件时,是否有人找到针对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"))
}

为了尝试解决建议的三个解决方案,我创建了一个包含三个项目的小测试解决方案:
  • TestApp(winforms应用程序),
  • SubControl(dll)
  • SubSubControl(dll)

  • 然后,我将SubSubControl嵌入SubControl中,然后将其中之一嵌入TestApp.Form中。

    此屏幕快照显示了运行时的结果。

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

    结论:似乎没有经过反射(reflection),构造函数内唯一可靠的是LicenseUsage,而构造函数外唯一可靠的是'IsDesignedHosted'(通过下面的BlueRaja)

    PS:请参阅下面ToolmakerSteve的评论(我尚未测试):“请注意,IsDesignerHosted的答案已更新为包括LicenseUsage ...,因此现在测试可以简单地是if(IsDesignerHosted)。另一种方法是test LicenseManager in constructor and cache the result。”

    10-06 01:00