2009-08-18 2 views
4

FrameworkElement 개체의 이벤트는 DataContextChanged입니다. 그러나 무시할 수있는 방법은 OnDataContextChanged입니다.WPF - "OnDataContextChanged"대체 메서드가없는 이유는 무엇입니까?

왜 그런가?

+0

왜 당신은 그것을 무시해야합니까? 그냥 DataContextChanged 이벤트를 수신 대기하는 것일까 요? – sisve

+0

음, 이것이 내가 결국 한 일입니다. 그러나 그 방법이 부족한 이유에 대해 궁금합니다. – Elad

답변

2

메소드가 가상 인 경우, 사용자는 기본 클래스 메소드를 호출하여 기본 기능을 보강하거나 기본 클래스 메소드를 호출하지 않아 기본 클래스 기능을 대체 할 수 있습니다. OnEvent() 메서드의 경우 기본 클래스 메서드를 호출하지 않으면 이벤트가 발생하지 않습니다 (이는 기본 클래스 메서드의 책임입니다). 기본 클래스가 OnEvent 메서드 내부에서 일종의 상태 관리를 수행하는 경우, 즉, 사용자가 기본 클래스 메서드에 대한 호출을 생략하도록 선택하면 파생 클래스가 우연히 개체의 상태를 무효화 할 수 있습니다. 문서에서는 "항상 기본 클래스 메서드를 호출하십시오"라고 지정할 수 있지만이를 적용 할 방법은 없습니다.

가상 OnEvent() 메서드가없는 이벤트를 볼 때 일반적으로이 메서드는 일종의 내부 상태 관리를 수행하며 클래스 디자이너는 해당 상태 관리를 실행하려고한다고 가정합니다. 이것은 FrameworkElement의 경우가 아니며 패턴을 따르지 않는 유일한 이벤트는 아니므로 추론이 무엇인지 궁금합니다.

리플렉터에서 주위를 파고 내가 이유를 발견 할 수 있는지 확인했습니다. 거기에 OnDataContextChanged() 메서드이지만 종속성 속성 변경 처리기이며 표준 이벤트 패턴을 따르지 않습니다. 이것이 아마 보호 된 가상으로 만들지 않은 이유 일 것입니다. 그것은 표준이 아니므로 혼란 스럽습니다. 그것은 정적이므로 어쨌든 오버라이드 할 수 없습니다. 종속성 속성 프레임 워크에 의해 자동으로 호출되었으므로이를 재정의 할 수 없기 때문에 정적 가상 대신 비공개라는 이유가 있다고 생각합니다.

당신은 일반 이벤트 패턴 노출 다른 패턴을 사용할 수 있습니다

class FrameworkElement 
{ 
    // difference: use DataContextPropertyChanged as the change callback 
    public static readonly DependencyProperty DataContextProperty = ... 

    protected virtual void OnDataContextChanged(...) 
    { 
     // raise the DataContextChanged event 
    } 

    private static void DataContextPropertyChanged(...) 
    { 
     ((FrameworkElement)d).OnDataContextChanged(...); 
    } 
} 

내 생각 엔 그들이이 왜하지 않았다을? 일반적으로 OnEvent()를 호출하여 이벤트를 발생시킵니다. DataContext가 변경되면 이벤트가 자동으로 발생하고 다른 시간에 이벤트를 발생시키는 것은 의미가 없습니다.

+0

정적 OnDataContextChanged 이벤트가 정적이 아닌 OnDataContextChanged 이벤트를 호출 할 수없는 이유는 없습니다. 물론 이름을 바꾸면 더 명확하게 할 수 있습니다. Overridable OnXxx 메서드를 제공하는 것이 표준 .NET 실습입니다. 허락하신다면, 당신이 언급 한 것처럼 함정이 있지만, 개발자가하는 일을 알기 위해 완화와 일정한 부담이 있습니다. –

+0

유효하지만 "사용자가 이벤트를 제기 할 수있는시기는 언제입니까?"라는 질문에는 대답하지 않습니다. 메서드가 보호되어 있으면 사용자가 그렇게 할 것을 결정할 때마다 메서드를 발생시킬 수 있습니다. 일부 정보가 누락되었습니다. 공개 이벤트가 아닌 방식으로 많은 내부 WPF 클래스에서이 이벤트를 사용하고 사용자가 어떤 방식 으로든 비헤이비어를 변경하면 위험 할 수 있습니다. – OwenP

1

좋은 질문입니다.

나는 단지 추측하고 있지만, 반사경을보고 나는 단지 게으름이라고 말하고 싶다. FrameworkElement에는 일련의 전체 이벤트에 대한 이벤트 정보 (위임자)를 유지 관리하는 일반 EventHandlersStore이 있습니다. CLR 이벤트의 추가 및 제거 로직 (예 : DataContextChanged)은 적절한 키를 사용하여 EventHandlersStore으로 간단하게 호출합니다.

모든 종류의 이벤트를 발생시키기 위해 호출되는 일반 RaiseDependencyPropertyChanged 메서드가 있습니다. RaiseDependencyPropertyChanged 메서드를 호출하는 전용 OnDataContextChanged 메서드도 있습니다. 그러나 정적이며 d-prop 메타 데이터의 일부로 등록됩니다.

따라서 간단히 말해서 우선 적용 가능한 OnDataContextChanged 메서드를 포함하지 않는 기술적 인 이유는 없습니다. 나에게 구현의 지름길처럼 보입니다.

이것은 단순히 학문입니까, 아니면 여기에서 뭔가를 달성하려고합니까?

+0

솔직히 그 뒤에 몇 가지 논리가 있는지 궁금합니다. 나에게도 의미가 없었습니다. 이벤트 등록은 내 필요에 맞게 좋습니다. 대단히 감사합니다! – Elad

0

실버 참고 : 실버 라이트 베타 4에서

DataContextChanged 이벤트가 없습니다 (물론이 아니 공공 이상).

Microsoft Connect bug report은 '고정'으로 표시되었지만 실제로 그 의미가 표시되지 않았습니다.

한편으로는 this one from CodeProject과 같은 해결 방법이 필요합니다. 이는 매우 간단하며 Microsoft가 실제로 이벤트를 공개하는 경우 쉽게 전환 할 수 있어야합니다.

0

종속성 속성은 일반적으로 변경 이벤트가 종속 속성 시스템 자체에서 관리 될 것으로 예상되므로 이벤트를 발생시키는 데 상응하는 가상 메서드가 없습니다.

는 그러나 무시할 수있는 것, 어떤 종속성 속성의 변화는과 같이 DependencyObject.OnPropertyChanged되어 처리하기 :

class MyClass : FrameworkElement { 

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { 
     base.OnPropertyChanged(e); 
     if (e.Property == FrameworkElement.DataContextProperty) { 
      // do something with e.NewValue/e.OldValue 
     } 
    } 

} 
+1

공! 나는 그것을 다시했고 첫 페이지에 나타 났던 정말로 오래된 질문에 대답했다. Grrr .... – Josh

관련 문제