Programing

Control의 생성자에서 디자인 모드 감지

lottogame 2020. 8. 31. 08:18
반응형

Control의 생성자에서 디자인 모드 감지


이 질문 에 이어 객체의 생성자 내에서 디자인 모드인지 런타임 모드인지 감지 할 수 있습니까?

나는 이것이 가능하지 않을 수 있으며 내가 원하는 것을 변경해야 할 것임을 알고 있지만 지금은이 특정 질문에 관심이 있습니다.


네임 스페이스 에서 LicenceUsageMode 열거를 사용할 수 있습니다 System.ComponentModel.

bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);

다음과 같은 것을 찾고 있습니까?

public static bool IsInDesignMode()
{
    if (Application.ExecutablePath.IndexOf("devenv.exe", StringComparison.OrdinalIgnoreCase) > -1)
    {
        return true;
    }
    return false;
}

프로세스 이름을 확인하여 수행 할 수도 있습니다.

if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
   return true;

구성 요소 ... 내가 아는 한 DesignMode 속성이 없습니다. 이 속성은 Control에서 제공합니다. 그러나 문제는 CustomControl이 디자이너의 Form에있을 때이 CustomControl이 런타임 모드에서 실행된다는 것입니다.

DesignMode 속성이 Form에서만 올바르게 작동한다는 것을 경험했습니다.


컨트롤 (양식, 사용자 컨트롤 등)은 다음 Component class상속합니다 bool property DesignMode.

if(DesignMode)
{
  //If in design mode
}

중대한

Windows Forms 또는 WPF 사용에는 차이가 있습니다 !!

그들은 다른 디자이너를 가지고 있고 다른 수표 가 필요 합니다 . 또한 Forms와 WPF 컨트롤을 혼합하면 까다 롭습니다. (예 : Forms 창 내부의 WPF 컨트롤)

Windows Forms 만 있는 경우 다음을 사용하십시오.

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);

당신이있는 경우 에만 WPF를 ,이 검사를 사용합니다 :

Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

Forms와 WPF를 혼합하여 사용 하는 경우 다음 과 같은 검사를 사용하십시오.

Boolean isInWpfDesignerMode   = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
Boolean isInFormsDesignerMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv");

if (isInWpfDesignerMode || isInFormsDesignerMode)
{
    // is in any designer mode
}
else
{
    // not in designer mode
}

현재 모드를 보려면 디버깅을위한 MessageBox를 표시 할 수 있습니다.

// show current mode
MessageBox.Show(String.Format("DESIGNER CHECK:  WPF = {0}   Forms = {1}", isInWpfDesignerMode, isInFormsDesignerMode));

말:

You need to add the namespaces System.ComponentModel and System.Diagnostics.


You should use Component.DesignMode property. As far as I know, this shouldn't be used from a constructor.


Another interesting method is described on that blog: http://www.undermyhat.org/blog/2009/07/in-depth-a-definitive-guide-to-net-user-controls-usage-mode-designmode-or-usermode/

Basically, it tests for the executing assembly being statically referenced from the entry assembly. It circumvents the need to track assembly names ('devenv.exe', 'monodevelop.exe'..).

However, it does not work in all other scenarios, where the assembly is dynamically loaded (VSTO being one example).


With cooperation of the designer... It can be used in Controls, Components, in all places

    private bool getDesignMode()
    {
        IDesignerHost host;
        if (Site != null)
        {
            host = Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
            if (host != null)
            {
                if (host.RootComponent.Site.DesignMode) MessageBox.Show("Design Mode");
                else MessageBox.Show("Runtime Mode");
                return host.RootComponent.Site.DesignMode;
            }
        }
        MessageBox.Show("Runtime Mode");
        return false;
    }

MessageBox.Show( lines should be removed. It only makes me sure it works correctly.


This is the method I used in my project:

//use a Property or Field for keeping the info to avoid runtime computation
public static bool NotInDesignMode { get; } = IsNotInDesignMode();
private static bool IsNotInDesignMode()
{
    /*
    File.WriteAllLines(@"D:\1.log", new[]
    {
        LicenseManager.UsageMode.ToString(), //not always reliable, e.g. WPF app in Blend this will return RunTime
        Process.GetCurrentProcess().ProcessName, //filename without extension
        Process.GetCurrentProcess().MainModule.FileName, //full path
        Process.GetCurrentProcess().MainModule.ModuleName, //filename
        Assembly.GetEntryAssembly()?.Location, //null for WinForms app in VS IDE
        Assembly.GetEntryAssembly()?.ToString(), //null for WinForms app in VS IDE
        Assembly.GetExecutingAssembly().Location, //always return your project's output assembly info
        Assembly.GetExecutingAssembly().ToString(), //always return your project's output assembly info
    });
    //*/

    //LicenseManager.UsageMode will return RunTime if LicenseManager.context is not present.
    //So you can not return true by judging it's value is RunTime.
    if (LicenseUsageMode.Designtime == LicenseManager.UsageMode) return false;
    var procName = Process.GetCurrentProcess().ProcessName.ToLower();
    return "devenv" != procName //WinForms app in VS IDE
        && "xdesproc" != procName //WPF app in VS IDE/Blend
        && "blend" != procName //WinForms app in Blend
        //other IDE's process name if you detected by log from above
        ;
}

Attention!!!: The code returned bool is indicating NOT in design mode!


    private void CtrlSearcher_Load(object sender, EventArgs e)
    {
           if(!this.DesignMode) InitCombos();
    }

You can use this

if (DesignerProperties.GetIsInDesignMode(this))
{
...
}

The LicenseManager solution does not work inside OnPaint, neither does this.DesignMode. I resorted to the same solution as @Jarek.

Here's the cached version:

    private static bool? isDesignMode;
    private static bool IsDesignMode()
    {
        if (isDesignMode == null)
            isDesignMode = (Process.GetCurrentProcess().ProcessName.ToLower().Contains("devenv"));

        return isDesignMode.Value;
    }

Be aware this will fail if you're using any third party IDE or if Microsoft (or your end-user) decide to change the name of the VS executable to something other than 'devenv'. The failure rate will be very low, just make sure you deal with any resulting errors that might occur in the code that fails as a result of this and you'll be fine.


If you want to run some lines when it is running but not in the Visual Studio designer, you should implement the DesignMode property as follows:

// this code is in the Load of my UserControl
if (this.DesignMode == false)
{
    // This will only run in run time, not in the designer.
    this.getUserTypes();
    this.getWarehouses();
    this.getCompanies();
}

참고URL : https://stackoverflow.com/questions/1166226/detecting-design-mode-from-a-controls-constructor

반응형