2012-04-12 4 views
5

항목 목록이 포함 된 사용자 정의 컨트롤이 있고 currentIndex가 변경 될 때 이벤트를 발생시킵니다. 또한 변경 될 때 두 가지 다른 메서드를 호출하여 두 가지 모양을 확인하고 변경해야합니다. 컨트롤 (이미지 변경 및 일부 버튼 차단/차단 해제).속성 변경 후 메서드 호출시기

내가 이미 알고 싶어하는 것은 호기심 때문입니다. 이미 작동하고 있기 때문에 언제 이러한 두 가지 방법을 호출하는 것이 더 적절합니까?

본인이 CurrentIndex 속성 내에서 호출해야합니까? OnCurrentIndexChanged(...) 안에 전화해야합니까? 수업 내에서 이벤트를 처리하고 거기에서해야합니까?

답변

6

표준 이벤트 생성 패턴을 구현하고 OnCurrentIndexChanged protected virtual을 생성하여 파생 클래스가 메서드를 재정의하고 이벤트 생성 및/또는 처리를 변경할 수 있다고 가정합니다.

불행히도 찻잎을 읽어야하는 이유는 입니다.은 누구나이 방법을 무시하고 싶은가요? 그리고 더 진지하게, 방법을 재정의 할 수있는 방법을 때 당신의 통제를 깰 수 있습니까? 코드를 잘 모르는 사람이라면 누구나 쉽게 추측 할 수 있습니다. .NET 프레임 워크 코드에서 사용되는 여기에 적용되는 원칙은 가능한 한 적게 수행하는 것입니다. 그냥 이벤트를 올리면됩니다. 파생 클래스가 어리석은 짓을하지만 base.OnCurrentIndexChanged를 호출하지 않는 것과 같이 완전히 공통적 인 경우 파손 가능성을 최소화합니다.

컨트롤의 동작은 UserControl의 구현 세부 사항입니다. 따라서 CurrentIndex 속성 설정자에서 속성을 변경 한 다음 OnCurrentIndexChanged()를 호출하십시오. 클래스에서 파생 된 사람은 필요한 경우 해당 동작을 무시할 수 있습니다. OnCurrentIndexChanged() 메서드를 호출하는 것을 잊었을 때 아무 잘못도 없습니다. 그러나 제어 변수 을 개인 대신에으로 보호해야한다고 유의하십시오. 그래서 그들은 수 있습니다 행동을 무시 해야하는 경우.

그리고 너무 짜증이 나면 주저하지 말고 가상 방법을 사용하지 마십시오. 수십만 명의 프로그래머가 컨트롤을 사용할 필요가 없습니다.

+0

상속받은 클래스가 실제로 내 기본 클래스를 오버라이드 할 수 있다는 사실을 고려해 볼 때, 접근법에 대한 약간의 관점을 제시한다. 고맙습니다. – PedroC88

2

사용자 정의 컨트롤에는 선택한 항목을 나타내는 속성이 있습니다. 그런 다음 객체 설정자에서 이벤트 메서드를 발생시켜 사용자 정의 컨트롤을 변경합니다. 그런 식으로 향후에 청취자를 더 추가해야하는 경우 setter 메서드에 다른 핸들러를 추가하면됩니다. 이것은 MVVM 응용 프로그램에서 매우 일반적이며 유지 관리가 용이합니다.

+0

그건 기본적으로 내가 가지고있는 것입니다, 당신은 객체 자체를 설정하지 않고 객체의 인덱스를 설정하고, 인덱스의 세터에서는 이벤트를 발생시킵니다. 다른 사람들을 같은 세터에서 호출해야하는지 모르겠습니다. 또는 이벤트를 발생시키는 방법 내에서? 또는 동일한 클래스 내의 대리인 내에 있습니까? 또는 다른 사람들이 생각 나게하는 곳. – PedroC88

+1

@ PedroC88 나는 속성의 설정자로부터 각 메서드를 호출 할 것이다. 나는 이것을 많이 사용했는데 컨트롤이 복잡해지면 메서드를 추가하는 것이 쉽습니다. INotifyPropertyChanged 인터페이스와 추상화의 요지입니다. – Josh

+0

그게 바로 지금 실제로 가지고있는 방법입니다, 나는 속성의 세터에서 두 가지 방법을 모두 호출, 난 그냥 더 나은 접근 방식 (그리고 왜)보고 싶었어요. 우리가 거기에 동의하는 것 같습니다. 추신 나는'InotifyPropertyChanged'를 구현하지 않고있다. – PedroC88

1

UserControl이 ListControl 역할을하기 때문에 두 이벤트와 두 가지 속성을 구현해야합니다.

public event System.EventHandler SelectedIndexChanged; 
public event System.EventHandler SelectionChangeCommitted; 

public int SelectedIndex { 
    get; 
    set; 
} 

public T SelectedItem { // Where T is whatever your type is 
    get; 
    set; 
} 

SelectedIndexChanged는 항상 항상 선택된 인덱스가 변경 될 때 트리거해야 할 활동을 위해 사용되어야한다 . SelectionChangeCommitted 사용자가 물리적으로 선택을 변경하면 트리거됩니다. 이 둘 사이의 구분은 중요한 차이점이며 .NET의 대부분의 컨트롤은이 패턴 (예 : ComboBox)을 따르지만 이벤트에 대해 동일한 이름을 사용할 수는 없습니다.

이제는 속성을 변경해야하는 컨트롤이 동일한 사용자 정의 컨트롤 내에있는 경우 물론 해당 컨트롤의 사용자 컨트롤 코드 내에서 해당 컨트롤을 처리해야합니다. 그렇지 않으면 코드는 사용자 컨트롤을 구현 한 사람에게 고아가되어야합니다 (예 :폼 또는 다른 사용자 컨트롤)에 이벤트를 가입시키고 작업을 수행하십시오.

순서는 정말 귀하의 요구 사항에 따라 다르지만 SelectedIndexChanged항상 제기해야

(그러나 여러 번 그 이상한 행동을 소개하는 것처럼 변화 당에 비해), 다시 SelectionChangeCommitted은 사용자에 의해 제기해야한다 (예. 설정 SelectedIndex 또는 SelectedItem).

좋은 경험 법칙은 사용자가 알고 있기 전에 내부 항목이 발생해야하며, 먼저 SelectedIndexChanged를 호출 한 다음 SelectionChangeCommitted를 호출해야합니다. 상관 없으면, 또는. 나중에 순서를 변경하면 컨트롤을 구현 한 사람이 변경 될 수 있으므로 결정이 확실한 지 확인하십시오.

두 가지의 차이점은 SelectedIndex이며 SelectedItem은 목록을 내부적으로 지우고 새 항목을 추가하는 등의 작업을 통해 업데이트되지만 실제 사용자 작업으로 인해 두 이벤트가 동시에 발생해야한다는 의미는 아닙니다. .

희망이 도움이됩니다.