it-swarm-ko.tech

Visual Studio 디자이너가 .NET 코드를 실행 중인지 확인하는 방법

Visual Studio 디자이너에서 Windows Forms 양식을 열면 코드에 오류가 발생합니다. 디자이너가 폼을 실제로 실행하는 경우와 달리 폼에서 코드를 분기하고 다른 초기화를 수행하고 싶습니다.

양식을 여는 디자이너의 일부로 코드가 실행되고 있는지 런타임에 어떻게 확인할 수 있습니까?

55
Zvi

"디자인 모드"인지 확인하려면 :

  • Windows Forms 구성 요소 (및 컨트롤)에는 DesignMode 속성이 있습니다.
  • Windows Presentation Foundation 컨트롤은 IsInDesignMode 연결된 속성을 사용해야합니다.
49
Roger Lipscombe
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
{
  // Design time logic
}
47
NET3

Control.DesignMode 속성은 아마도 당신이 찾고있는 것입니다. 컨트롤의 부모가 디자이너에서 열려 있는지 알려줍니다.

대부분의 경우 잘 작동하지만 예상대로 작동하지 않는 경우가 있습니다. 첫째, 컨트롤 생성자에서 작동하지 않습니다. 둘째, "손자"컨트롤의 경우 DesignMode가 false입니다. 예를 들어 UserControl에서 호스팅되는 컨트롤의 DesignMode는 UserControl이 부모에서 호스팅 될 때 false를 반환합니다.

매우 쉬운 해결 방법이 있습니다. 다음과 같이 진행됩니다.

public bool HostedDesignMode
{
  get 
  {
     Control parent = Parent;
     while (parent!=null)
     {
        if(parent.DesignMode) return true;
        parent = parent.Parent;
     }
     return DesignMode;
  }
}

그 코드를 테스트하지는 않았지만 should 작동합니다.

19
JohnV

가장 안정적인 방법은 다음과 같습니다.

public bool isInDesignMode
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        bool res = process.ProcessName == "devenv";
        process.Dispose();
        return res;
    }
}
15
GWLlosa

가장 안정적인 방법은 DesignMode 속성을 무시하고 응용 프로그램 시작시 설정된 고유 한 플래그를 사용하는 것입니다.

수업:

public static class Foo
{
    public static bool IsApplicationRunning { get; set; }
}

Program.cs :

[STAThread]
static void Main()
{
     Foo.IsApplicationRunning = true;
     // ... code goes here ...
}

그런 다음 필요할 때마다 플래그를 확인하십시오.

if(Foo.IsApplicationRunning)
{
    // Do runtime stuff
}
else
{
    // Do design time stuff
}
13
Marty Dill

디자이너는 이제 자체 프로세스를 가지고 있기 때문에 VS2012에서 devenv 접근 방식이 작동을 멈췄습니다. 여기에 현재 사용중인 솔루션이 있습니다 ( 'devenv'부분은 레거시를 위해 남아 있지만 VS2010이 없으면 테스트 할 수는 없습니다)).

private static readonly string[] _designerProcessNames = new[] { "xdesproc", "devenv" };

private static bool? _runningFromVisualStudioDesigner = null;
public static bool RunningFromVisualStudioDesigner
{
  get
  {
    if (!_runningFromVisualStudioDesigner.HasValue)
    {
      using (System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess())
      {
        _runningFromVisualStudioDesigner = _designerProcessNames.Contains(currentProcess.ProcessName.ToLower().Trim());
      }
    }

    return _runningFromVisualStudioDesigner.Value;
  }
}
5
Johny Skovdal

Visual Studio Express 2013에서도 동일한 문제가 발생했습니다. 여기에서 제안한 많은 솔루션을 시도했지만 저에게 도움이 된 솔루션은 다른 스레드에 대한 답변 입니다. 이제까지 깨진 :

protected static bool IsInDesigner
{
    get { return (Assembly.GetEntryAssembly() == null); }
}
4
GeeC
using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
{
    bool inDesigner = process.ProcessName.ToLower().Trim() == "devenv";
    return inDesigner;
}

위의 코드를 사용하여 (using 문 추가) 어떤 경우에는 실패합니다. 시작시 디자이너가로드되는 양식에 직접 배치 된 usercontrol의 생성자에서 테스트. 그러나 다른 곳에서 작동합니다.

모든 위치에서 나를 위해 일한 것은 다음과 같습니다.

private bool isDesignMode()
{
    bool bProcCheck = false;
    using (System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess())
    {
        bProcCheck = process.ProcessName.ToLower().Trim() == "devenv";
    }

    bool bModeCheck = (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime);

    return bProcCheck || DesignMode || bModeCheck;
}

어쩌면 조금 과잉 일 수도 있지만 효과가 있으므로 나에게 충분합니다.

위에서 언급 한 예제에서 성공한 것은 bModeCheck이므로 DesignMode가 잉여 일 수 있습니다.

3
Martin
/// <summary>
/// Are we in design mode?
/// </summary>
/// <returns>True if in design mode</returns>
private bool IsDesignMode() {
    // Ugly hack, but it works in every version
    return 0 == String.CompareOrdinal(
        "devenv.exe", 0,
        Application.ExecutablePath, Application.ExecutablePath.Length - 10, 10);
}
3
pintergabor

해킹 적이지만 VB.NET 을 사용하고 Visual Studio에서 실행중인 경우 My.Application.Deployment.CurrentDeployment 아무것도 아님 아직 배포하지 않았기 때문입니다. C #에서 동등한 값을 확인하는 방법을 잘 모르겠습니다.

2
Joel Coehoorn
System.Diagnostics.Debugger.IsAttached
1
Bob King

디버그 모드에서 실행하는 것이 실제 카운트인지 확실하지 않지만 쉬운 방법은 코드에 System.Diagnostics.Debugger.IsAttached를 확인하는 if 문을 포함시키는 것입니다.

1
Adrian Anttila

프로젝트를 실행할 때 이름에 ".vshost"가 추가됩니다.

그래서 나는 이것을 사용합니다 :

    public bool IsInDesignMode
    {
        get
        {
            Process p = Process.GetCurrentProcess();
            bool result = false;

            if (p.ProcessName.ToLower().Trim().IndexOf("vshost") != -1)
                result = true;
            p.Dispose();

            return result;
        }
    }

그것은 나를 위해 작동합니다.

1
Andy

디자인 타임에 전혀 필요하지 않은 속성을 만든 경우 DesignerSerializationVisibility 속성을 사용하여 숨김으로 설정할 수 있습니다. 예를 들면 다음과 같습니다.

protected virtual DataGridView GetGrid()
{
    throw new NotImplementedException("frmBase.GetGrid()");
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ColumnCount { get { return GetGrid().Columns.Count; } set { /*Some code*/ } }

NotImplementedException()을 사용하여 양식을 변경하고 저장하려고 할 때마다 Visual Studio 충돌이 중지되었습니다. 대신 Visual Studio는이 속성을 serialize하고 싶지 않다는 것을 알고 있으므로 건너 뛸 수 있습니다. 양식의 속성 상자에 이상한 문자열 만 표시되지만 무시하는 것이 안전합니다.

이 변경 사항은 다시 빌드 할 때까지 적용되지 않습니다.

1
Bolek

우리는 UserControls에서 다음 코드를 사용하고 작동합니다. 다른 멤버가 지적한대로 사용자 지정 사용자 정의 컨트롤을 사용하는 앱에서는 DesignMode 만 사용할 수 없습니다.

    public bool IsDesignerHosted
    {
        get { return IsControlDesignerHosted(this); }
    }

    public bool IsControlDesignerHosted(System.Windows.Forms.Control ctrl)
    {
        if (ctrl != null)
        {
            if (ctrl.Site != null)
            {
                if (ctrl.Site.DesignMode == true)
                    return true;
                else
                {
                    if (IsControlDesignerHosted(ctrl.Parent))
                        return true;
                    else
                        return false;
                }
            }
            else
            {
                if (IsControlDesignerHosted(ctrl.Parent))
                    return true;
                else
                    return false;
            }
        }
        else
            return false;
    }
1
Kalle

컨트롤의 DesignMode 속성을 확인하십시오.

if (!DesignMode)
{
//Do production runtime stuff
}

구성 요소가 아직 초기화되지 않았으므로 생성자에서 작동하지 않습니다.

1
Ryan Steckler
System.ComponentModel.Component.DesignMode == true
1
ShuggyCoUk

다른 하나는 다음과 같습니다.

        //Caters only to thing done while only in design mode
        if (App.Current.MainWindow == null){ // in design mode  }

        //Avoids design mode problems
        if (App.Current.MainWindow != null) { //applicaiton is running }
0
John Peters

폼이나 컨트롤에있는 경우 DesignMode 속성을 사용할 수 있습니다.

if (DesignMode)
{
        DesignMode Only stuff
}
0
Akselsson

적어도 이전 버전의 Visual Studio에서는 DesignMode 속성이 버그가 있음을 알았습니다. 따라서 다음 논리를 사용하여 직접 만들었습니다.

Process.GetCurrentProcess().ProcessName.ToLower().Trim() == "devenv";

해킹의 종류, 나는 알고 있지만 잘 작동합니다.

0
Eyvind

여기서 대부분의 답변을 테스트 한 후 불행히도 아무것도 도움이되지 않았습니다 (VS2015). 그래서 DesignMode는 Control 클래스의 보호 속성이므로 JohnV 's answer 에 약간의 왜곡을가했습니다.

먼저 Reflection을 통해 DesignMode의 속성 값을 반환하는 확장 메서드를 만들었습니다.

public static Boolean GetDesignMode(this Control control)
{
    BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
    PropertyInfo prop = control.GetType().GetProperty("DesignMode", bindFlags);
    return (Boolean)prop.GetValue(control, null);
}

그런 다음 JohnV와 같은 기능을 만들었습니다.

public bool HostedDesignMode
{
    get
    {
        Control parent = Parent;
        while (parent != null)
        {
            if (parent.GetDesignMode()) return true;
            parent = parent.Parent;
        }
        return DesignMode;
    }
}

이것은 모든 ProcessName 엉망을 피하면서 나를 위해 일한 유일한 방법이며 반사를 가볍게 사용해서는 안되지만이 경우 모든 차이가있었습니다! ;)

편집 :

두 번째 함수를 다음과 같이 확장 메소드로 만들 수도 있습니다.

public static Boolean IsInDesignMode(this Control control)
{
    Control parent = control.Parent;
    while (parent != null)
    {
        if (parent.GetDesignMode())
        {
            return true;
        }
        parent = parent.Parent;
    }
    return control.GetDesignMode();
}
0
Gpower2

이 문제를 해결하기 위해 다음과 같이 코딩 할 수도 있습니다.

private bool IsUnderDevelopment
{
    get
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
        if (process.ProcessName.EndsWith(".vshost")) return true;
        else return false;
    }

}
0