2008-11-11 4 views
10

스레드를 시작하고 파일을 열고 다른 클래스의 입력을 기다리는 개체가 있습니다. 입력을 받으면 디스크에 기록합니다. 기본적으로 스레드로부터 안전한 데이터 로깅 클래스입니다..NET Windows Forms 디자인 타임 규칙

다음은 이상한 부분입니다. 객체를 사용하는 디자이너 (Visual   Studio   2008)에서 양식을 열면 파일이 만들어집니다. 그것은 분명히 디자인 시간 vhost 프로세스에서 실행 중입니다 ...

이상한 일은 다른 프로젝트에서 문제를 재현하지 못했습니다. 디자이너와 코드에서 실행되는 코드의 규칙이 무엇인지 잘 모르겠습니다. 예를 들어, Windows Forms 생성자에서 파일을 만드는 것은 실제로 디자인 타임에 파일을 만들지 않습니다 ...

설명은 무엇입니까? 레퍼런스가 있습니까?

답변

11

코드가 디자인 타임에 있는지 확인하기 위해 LicenseManager의 UsageMode를 확인할 수 있습니다. 당신은

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace Test 
{ 
    public class ComponentClass : Component 
    { 
     public ComponentClass() 
     { 
      MessageBox.Show("Runtime!"); 
     } 
    } 
} 

이 구성 요소 디자이너에서 폼에 추가 가져옵니다

System.ComponentModel.LicenseManager.UsageMode == 여기 System.ComponentModel.LicenseUsageMode.Designtime

빠른 예입니다 immediatly 메시지 상자를 얻을 것이다. 구성 요소가 폼에 추가 할 때 코드가 if 문을 추가 한 후 설계 시간

using System; 
using System.ComponentModel; 
using System.Windows.Forms; 

namespace Test 
{ 
    public class ComponentClass : Component 
    { 
     public ComponentClass() 
     { 
      if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) 
      { 
       MessageBox.Show("Runtime!"); 
      } 
     } 
    } 
} 

에없는 경우

문 확인할 경우 간단한을 추가 할 수 있습니다이를 방지하기 위해, 메시지 박스는 더 이상 나타나지 않습니다 디자이너를 통해.

이 정보가 도움이되기를 바랍니다. 의 Form_Load에 다음

public static bool DesignMode 
{ 
    get { return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"); } 
} 

:

-jeremy

0

디자이너와 관련해서는 안되는 몇 가지 사항이 있습니다. 어려운 증거는 없지만 Windows Forms 디자이너가 기본 생성자를 제거 할 때 Windows Forms 디자이너가이를 싫어한다는 것을 알았습니다. 그냥 새로운 과부하를 만들고 빈 생성자를 그대로 두십시오.

또한 상속받은 기본 클래스에서 이벤트를 피하려고합니다.

2

또한 비주얼 스튜디오 디자이너는 코드가 실행되고 있는지 확인하려면이 사용할 수 그러나

if (!DesignMode) 
{ 
    // Run code that breaks in Visual Studio Designer (like trying to get a DB connection) 
} 

을,이 작 우아한 LicensManager.UsageMode을 사용하는 것보다 우수하지만 작동합니다 (Microsoft에서 Visual Studio가 실행되는 프로세스의 이름이 변경 될 때까지).

+0

남자, "덜 우아한"방법이 유일한 방법입니다. LicensManager.UsageMode가 작동하지 않습니다. 디자이너가 사용자 정의 컨트롤의 '속성 얻기'메소드를 호출 할 때. – Soonts

11

디자이너에서 해당 클래스를 편집 할 때 컨트롤 또는 폼의 생성자가 실행되지 않고 OnLoad가 호출되지 않습니다. 때때로 디자이너에서 하나의 값을 설정하는 데 사용했습니다 (예 : 디자이너에서 모든 자식 컨트롤을 표시하도록 설정)하지만 일부는 생성자의 다른 기본값으로 재정의합니다 (예 : 특정 하위 컨트롤 만 숨기면 표시됨). 상태 표시 줄의 표시 등).

그러나 컨트롤이 설계자의 다른 컨트롤이나 폼에 자식으로 배치 된 경우 이 실행됩니다. OnLoad도 실행됩니다. 이것은 로깅 코드가 실수로 디자이너에서 트리거되는 방식 일 수 있습니다.

디자인과 런타임을 감지하기 위해 an answer에서 another question까지는 몇 가지 일반적인 접근법에 의해 반환 된 값을 보여주는 몇 가지 비공식 테스트의 스크린 샷이 있습니다. 디자이너에서 편집중인 폼 또는 컨트롤의 하위 컨트롤 (두 수준 아래)에 대한 자식 컨트롤이 자체 DesignMode == false로 표시되므로 일반 속성 검사가 코드 보호에 실패합니다 (예 : OnLoad 메서드) 디자이너에서 추가 된 컨트롤 내에 중첩 된 컨트롤 예상대로 DesignMode를 확인했다면, 그 체크를 돌아 다니게하는 중첩이 될 수 있습니다. 또한 항상 생성자 내에서 DesignMode == false를 봅니다.

또한 LicenseManager.UsageMode 검사 에만은 생성자 내에 DesignTime이 표시됩니다. OnLoad가 호출되면 RunTime LicenseContext 내에 있습니다. 가장 완벽한 솔루션은 컨트롤 또는 폼 (또는 구성 요소)의 생성자에서 LicenseManager.UsageMode를 확인하고 나중에 디자이너에서 실행해서는 안되는 코드를 실행하지 않도록 나중에 확인할 수있는 멤버 변수 또는 속성에 설정을 저장하는 것입니다 중첩 된 경우에도. 중첩을 고려하지만 생성자 바깥에서만 작동하는 다른 질문에 대해서는 another answer에 또 다른 접근법이 있습니다.

public static bool IsAnyInDesignMode(Control control){ 
    while(control != null){ 
     if(control.Site != null && control.Site.DesignMode) 
      return true; 
     control = control.Parent; 
    } 
    return false; 
} 

이것은 컨트롤이 다른 컨트롤에 의해 생성 된 아이 인 경우를 처리 :이 어쨌든 부활 된 이후

+0

나는 이것이 나를 도울 수 있다고 생각한다. 감사! ++ – John

+0

정정 : 그것은 나를 도와 줬다. :) – John

+0

쿨! 그것을 듣고 기뻐. –

2

음, 여기 내가 디자인 모드에있어 여부를 결정하는 데 사용하는 기능입니다. DesignMode 속성은 디자이너 자체에서 만든 컨트롤에만 설정됩니다.