2011-02-01 3 views
2

이벤트 처리에 대한 개념적 질문이 있습니다.여러 EventHandler/대리자 블록 - 처리를 중지하는 방법?

하나의 이벤트에 여러 개의 익명 대리자 블록이 할당되도록하십시오. 기본적으로 onedelegate는 검사를 수행하고 검사가 실패하면 결국 블록 처리를 중단해야합니다.

모든 항목을 단일 대리자 블록에 넣고 필요할 때마다 리턴하는 것이 가능하다는 것을 알고 있습니다.

그러나 여러 개체에서 확인이 필요한 경우 해당 코드가 모든 개체에 있어야합니다.

object1.SomeEvent += delegate { 
    // check something 
    if (somethingHappened) { 
    // STOP! 
    return; 
    } 
    // do something for object1 (if nothing happened) 
} 

object2.SomeEvent += delegate { 
    // check something 
    if (somethingHappened) { 
    // STOP! 
    return; 
    } 
    // do something else for object2 (if nothing happened) 
} 

이렇게 할 수 있습니까? 그렇다면 어떻게해야합니까?

EventHandler checkSomething = delegate { 
    if (somethingHappened) { 
    // STOP! 
    // What to do here? 
    return; // This won't prevent the other event handlers from executing. :(
    } 
}; 

object1.SomeEvent += checkSomething; 
object1.SomeEvent += delegate { 
    // do something for object1 (if nothing happened) 
}; 

object2.SomeEvent += checkSomething; 
object2.SomeEvent += delegate { 
    // do something else for object2 (if nothing happened) 
} 

EDIT :
실제 시나리오 :

개체 유형있는 UIButton (MonoTouch/UIKit)로하고, 사용자가 그 프레임 내에서 그들 (도청 정지 할 때마다 이벤트 TouchUpInside 나타날).

두 단추가 일반적으로하는 일을하지 못하도록하고 오류 상태에 대해 경고하는 UIAlertView를 표시하는 오류 조건이 있습니다.

+2

실제로 이벤트가 작동하는 방식이 아닙니다. 한 구독자는 다른 구독자에게 이벤트 전파를 중지 할 수 없습니다. 그게 니가하려고하는 것 같아, 맞지? 개체에 대한 정보를 조금 더 제공하면 이벤트가 발생하고 각 구독자가 어떤 작업을 수행할지, 어떤 조건으로 전파를 막을지를 사람들은 작동 할 수있는 솔루션을 제공 할 수 있습니다 –

+0

CancelEventArgs 및 해당 사용법을 확인하십시오. WinForms 시스템 전반에 걸쳐. –

답변

1

object1과 object1의 클래스를 소유하고 있다면 단순히 이벤트를 호출하는 대신 이벤트의 호출 목록을 직접 살펴볼 수 있습니다.

하지만 정말 엉망이 될 것입니다. 예를 들어 2 개의 이벤트로 나누는 것과 같은 대체 설계를 고려하십시오 (점검을 수행하려면 1 개). 나는 당신이 원하는 것을 제대로 이해하고

+0

불행히도, 나는 수업을 소유하지 않습니다. 개체는 인스턴스 UIButton (MonoTouch/UIKit)이며 이벤트는 TouchUpInside입니다 (기본적으로 사용자가 단추를 누르지 않았을 때 트리거됩니다). – riha

+3

다른 클래스를 추가하여 항상 문제를 해결할 수 있습니다. 하나는 버튼 이벤트 (1x)에 가입하고 다른 코드는 2 개의 이벤트를 노출합니다. –

+0

이렇게하면 좋은 결과를 얻을 수는 있지만 너무 많은 오버 헤드가 발생합니다. (내 기본 목표는 코드를 단순화하는 것이 었습니다.) – riha

-1

, 가장 좋은 방법은 이것이다 :

EventHandler checkSomething = delegate(object sender, EventArgs e) { 


      if (somethingHappened) { 
       //STOP 
       return; 
      }//end if 

      UIButton theButton = (UIButton)sender; 
      if (theButton.Title == "Button1") { 
      //do something for Object1 
      }//end if 

      if (theButton.Title == "Button2") { 
      //do something for Object 2 
      } 
}; 
+0

유망 보인다. Object1은 해당 컨텍스트의 클래스 또는 인스턴스입니까? 나에게 클래스 이름처럼 보인다. 두 객체가 같은 클래스이므로, 여전히 작동할까요? – riha

+0

먼저, 맞춤 수업인지 알려주세요. –

+0

번호 질문에 대한 편집을 참조하십시오. – riha

0

간단히 CancelEventArgs을 사용하여 다음과 같은 eventhandlers가 처리를 중지해야하는 경우 true에 취소 설정합니다.

EventHandler checkSomething = delegate { 
    if (somethingHappened) { 
    // STOP! 
    e.Cancel = true; 
    return; // This won't prevent the other event handlers from executing. :(
    } 
}; 

object1.SomeEvent += checkSomething; 
object1.SomeEvent += delegate { 
    if(!e.Cancel) { 
    // do something for object1 (if nothing happened) 
    } 
}; 

object2.SomeEvent += checkSomething; 
object2.SomeEvent += delegate { 
    if(!e.Cancel) { 
    // do something else for object2 (if nothing happened) 
    } 
} 
+0

좋은 접근 방식이지만 이벤트가 작동하려면 CancelEventHandler 유형이어야합니다. 나는 클래스를 소유하지 않으므로 해당 유형으로 이벤트를 변경할 수 없습니다. – riha

+0

좋습니다. 아주 좋지는 않지만 모든 이벤트 가입자가 일반적으로 볼 수있는 다른 클래스에 Cancel-Flag를 저장할 수 있습니다 ... –

+0

이것은 다소 이벤트 발주 순서 (부여 된 AFAICT로 간주되지 않음)에 의존하므로, 오히려 그것을 그렇게 구현하지 않으려 고합니다. – riha

관련 문제