2012-09-19 2 views
2

다른 가상 클래스 ("컨트롤")를 가진 다른 클래스에서 상속 한 클래스가 있습니다.C# Winforms 디자이너가 'new'대신 기본 속성을 호출합니까?

이 속성을 덮어 쓸 수 없으므로 내 속성과 관련된 '새'키워드를 사용하고 있습니다.

런타임에이 속성은 올바른 컨텍스트에서 원하는대로 호출됩니다.

디자이너에서 양식을 열면 디자이너가 '새'컨트롤 대신 base.Controls를 호출합니다.

뭔가 누락되었거나 winforms 디자이너에서이 잘못된 동작입니까?

편집에 대한 자세한 설명은 해당 코드를 추가하십시오. 내 intializecomponent에 다음 코드에 도착하면

public partial class BauerGroupBox : ComponentFactory.Krypton.Toolkit.KryptonGroupBox 
    { 
     public BauerGroupBox() 
     : base() 
     { 
     } 
     public new Control.ControlCollection Controls 
     { 
     get 
     { 
      MessageBox.Show("GOT THERE"); 
      return this.Panel.Controls; 
     } 
     } 
    } 

이 : 나는 내 코드에 새로운 'BauerGroupBox'를 추가하면

BauerGroupBox thisBox = new BauerGroupBox() 
thisBox.Controls.Add(something) 

, 그것은 잘 작동 나는 다음과 같은 클래스가 있습니다. 그러나 디자이너에서 코드를 열면 (심지어 devenv 디버깅을 사용하는 동안) 메시지 상자가 표시되지 않고 중단 점에 도달하지 않습니다.

내 앱을 실행할 때 중단 점이 발생합니다.

답변

3

당신이 뭔가를 놓쳤습니다 - 당신이 설명하는 것은 올바른 행동입니다.

InitializeComponent()을 호출 한 직후 새로운 Controls 속성을 다시 채울 수 있습니다. 좋아요 :

public MyForm() { 
    InitializeComponent(); 
    this.Controls.AddRange(base.Controls); 
} 

그러나 Controls 속성을 "오버라이드"하려고합니까? 새로운 비표준 행동은 무엇입니까? 나는 더 나은 대안이 있다고 믿는다.

+0

자세한 내용은 내 질문에 편집되었습니다. 기본 컨트롤의 디자인 방식에 따라 사용자가 컨트롤 컬렉션에 직접 추가하는 것을 원하지 않지만 대신 사용자가 컨트롤 컬렉션에 control.panel.controls를 추가하기를 원합니다. 이 작업을 자동으로 수행하기 위해 '경로 통과'를 작성하려고합니다. – greggorob64

1

새 키워드의 작동 방식을 잘못 이해했습니다. New는 속성을 무시하지 않고 숨 깁니다. 기본 요소로 객체를 참조하면 새 객체가 아닌 기본 속성이 계속 호출됩니다. 새로운 것을 사용하는 유일한 방법은 그것을 새로운 것으로 참조하는 것입니다. 즉.

public class A { 
    public A1 {get;set;} 
} 

public class B : A { 
    public new A1 {get;set;} 
} 

B b = new B(); 
A a = b; 

a.A1; // references A.A1 
b.A1; // references B.A1 
+0

코드 샘플로 내 질문을 편집했습니다. 나는 단지 "b.a1"이 호출되기를 바란다. 런타임에이 양식은 올바른 "b.a1"을 호출합니다. 그러나 디자이너는 "a.a1"을 호출하려고합니다. 경험상 디자이너가 디자인 할 때 기본 클래스의 인스턴스를 인스턴스화하므로 시각적 인 매력을 사용하면서 추상 기본 클래스에서 파생 될 수 없습니다. – greggorob64

+1

@ greggorob64 - 예, 알고 있습니다. 요점은 디자이너가 Control 기본 클래스를 호출하여 일반적으로 작동하므로 숨겨진 클래스를 호출하지 않는다는 것입니다. 이것이 바로 대체 (override)와 새 (new)의 차이점입니다. 그들은 서로 다른 두 가지 일을하며, 다른 일을하도록 만들 수 없습니다. –

+0

나는 아직도 내가 누락 된이 줄을 보지 않는다고 생각한다. private BauerGroupBox bauerGroupBox1; this.bauerGroupBox1.Controls.Add (this.bauerButton1); '새'속성을 호출해야합니다. "새로운 작품"을 오해하지 마십시오. 이 경우 올바른 호출 절차입니다. 그렇지 않습니까? – greggorob64

1

은 내가 당신의 상황을 이해 생각, 그래서 내가 디자이너가 무엇을하고 있는지 설명하자 :

첫째, 런타임에, 당신은 효과적으로 BauerGroupBox 컨트롤의 인스턴스를 실행하고 있습니다. (즉,이 파생 된 유형의 참조 인 BauerGroupBox을 통해 Controls 속성에 액세스하고 @Mystere Man이 올바르게 주장한 것처럼 BauerGroupBox.Controls 멤버는 상속 된 멤버를 숨 깁니다 (마지막 정의 된 위치) - 그것을 무시하지 않습니다. 문제의 문제 버

는 디자인 타임에, BauerGroupBox 컨트롤의 디자이너 , 당신은 BauerGroupBox "실행"인스턴스 아니라는 것이다, 대신 당신이 designing 이래저래 프로토 타입은 ComponentFactory.Krypton.Toolkit.KryptonGroupBox을 기반으로하며 실제로는 "실행중인"컨트롤 유형입니다.

디자이너를 반복하면 BauerGroupBox의 디자이너는 BauerGroupBox의 인스턴스가 실행되지 않고 ComponentFactory.Krypton.Toolkit.KryptonGroupBox의 인스턴스가 실행됩니다. 디자이너가 아니기 때문에 아무런 BauerGroupBox이 존재합니다.

이제 조금 더 혼란을 더하기 위해 (아무 것도 실제로는 전혀 생각지 않는다.) 다른 컨트롤의 다른 디자이너에게 가서 양식을 말하면 , 그리고 BauerGroupBox의 인스턴스를 드래그 앤 드롭하고 컨트롤을 추가하면 메시지 상자가 나타납니다.이 경우 "런타임"의 경우와 마찬가지로 효과적으로 BauerGroupBox ...이 경우에는 BauerGroupBox을 설계하지 않습니다.

다른 @Dai은 무엇 당신이하려는 것은 여기에 컨트롤을 추가하는 사람을 방지하는 경우에, 당신은 다른 디자인 계획을 따라야 언급 한 바와 같이 예를 들어,

protected virtual Control.ControlCollection CreateControlsInstance(); 

메소드를 오버라이드 (override).

+0

약 12 ​​번째 발언에서 나는 결국 내 길의 잘못을 깨달았습니다. 필자의 목표는 여전히 controls.add의 모든 참조를 panel.controls.add에서 수백 개의 인스턴스를 대체 할 필요가 없다는 것입니다. – greggorob64

+0

방금 ​​답변에 다른 단락을 추가했습니다.'protected virtual Control.ControlCollection CreateControlsInstance()'메소드를 재정의 할 수 있습니다. 이 클래스에서, 당신은'Control.ControlCollection'에서 파생 된 클래스의 인스턴스를 반환 할 것이고, 그 소유자는'BauerGroupBox' 타입을 "알"것입니다. 그런 다음 실제 가상 BauerGroupBox.Add (컨트롤 값) 메서드를 재정의하고 추가하면 부모 컨트롤에 추가 경로가 지정됩니다. 그러나 그것은 당신이 정말로 그런 식으로 가고 싶어한다고 가정하고 있습니다. – fernandoespinosa

관련 문제