2013-09-21 2 views
2

Visual Basic.net에서는 목록이 변경 될 때마다이 이벤트를 호출 할 수 있도록 T 목록에 이벤트 처리기를 추가 할 수 있습니까?목록에 대한 이벤트 처리기 추가

예를 들어 Schedule이라는 클래스가 있고이 Schedule에 ScheduleItem 목록이있는 경우이 목록이 변경 될 때마다 호출 할 이벤트를 어떻게 추가 할 수 있습니까?

답변

2

목록이 바뀔 때 이벤트를 발생시키는 컬렉션이 있지만 (BindingList(of T)) 이벤트는 목록이있는 클래스/양식에서만 사용할 수 있습니다. 보다 광범위한 구현을 위해서는 Schedule 클래스가 이벤트를 발생시킬 수 있습니다.

  1. 확신은 Schedule 목록을 변경합니다합니다. 즉, List(Of T)은 비공개 회원이어야합니다. 다른 객체는 모든 변경 사항을 완전히 인식하여 누락되지 않도록 변경해야합니다.

  2. 변경 이벤트가 무엇인지 결정하십시오. 항목을 추가하거나 삭제하는 것은 명백하지만 ScheduleItem에있는 내용에 따라 .StartTime 또는 유사한 속성이 이벤트가 될 수도 있습니다. 다만, Schedule 추가하거나 내부 목록에서 항목을 삭제마다 추가 및 삭제를 들어

  3. 을 (즉, 실제로 항목 클래스에 INotifyPropertyChanged을 필요로), 그것은 가입자를 알리기 위해 이벤트를 발생시킬 것이다.

  4. 누가 이러한 이벤트를 소비합니까? 양식? 다른 클래스 구조체?

    Public Class Schedule 
        Private MyList as List (Of ScheduleItem) 
    
        Public Event ScheduleChanged(sender As Object, e As EventArgs) 
    
        ... 
        Public Sub AddItemToSchedule(....) 
         ' I have no idea what is in a ScheduleItem.... 
         ... 
         MyList.Add(si) 
         ' the point is that if it gets added/not a dupe etc, then: 
         ' tell any subscribers that the sched changed: 
         RaiseEvent ScheduleChanged(Me, New EventArgs()) 
        End Sub 
    
        Public Sub RemoveItem(...) 
         ' do whatever to remove an item 
         ' ... 
         MyList.Remove(si) 
         ' tell subscribers the sched changed 
         RaiseEvent ScheduleChanged(Me, New EventArgs()) 
        End Sub 
    End Class 
    

    개인 컬렉션에 대체가 Schedule입니다 :

이 작업을 수행하는 간단한 방법은, 한 번에 모든 변경 사항 목록 사용자 지정 이벤트 '소유'클래스에서 일어나고있는 Collection(of T)과 같은 것을 상속합니다. 이벤트의 가입자 :

Public Class SomeOtherClass 

    ' These need a reference to the Schedule object 
    Private WithEvents Sched As Schedule 
    ... 
    Public Sub New(scObj As Schedule) 
     Sched = scObj 
    End Sub 
End Class 

SomeOtherClass 이제 왼쪽 VS 드롭 다운에 새 항목이 관련 이벤트 복근해야합니다 :

Private Sub Sched_ScheduleChanged(sender As Object, 
        e as EventArgs) Handles Sched.ScheduleChanged 
    ' add code here to respond to schedule changes 

End Sub 

사용법 : 무엇이든을

Dim foo = New SomeOtherClass(SchedObj) 

를 만드는 SomeOtherClass 개체는 생성자의 Schedule 개체를 전달합니다. Schedule으로 만들면 Me이됩니다.모든 경우에 존재하는 Schedule 요구를

Public Sub New() 
    Sched = mainSchedInstance 
End Sub 

또는 코드는 Nothing 객체의 이벤트에 후크하려고됩니다 SomeOtherClassSchedule에 액세스 할 수있는 경우

당신은 생성자 인수를 포기 할 수 있습니다.

노트

  • 모든 이벤트에 Sched 객체 (Me)를 통과 이상하게 보일 수도 (다른 ScheduleChanged 이벤트를 보낼 것입니다 누구?). 그러나 VS 코드 분석 도구는 Object sender, EventArgs e 이외의 이벤트 서명을 처리합니다.
  • 변경 내용이 과 같은 이벤트에 정보를 전달하려면 EventsArgs에서 상속받은 클래스를 만들고 원하는 속성을 추가하십시오. 그 중 하나는 ScheduleItem이 이벤트에 대해 알고 Foo.ScheduleSomeOtherClass 요구했다의 예를 들어,이를 구현하는 다른 방법이 있습니다

을 추가 할 수 있습니다. 이 경우 Schedule은 여전히 ​​이벤트를 생성하고 Foo 이벤트를 구독 한 다음 이벤트이벤트를 발생시키고 이벤트 args를 전달합니다. 다른 배우들은 Foo에 이벤트를 구독합니다. 이것을 이벤트 버블 링 (bubbling up)이라고합니다.


또한 한 가지 방법으로 작은 클래스를 만들 수 있으며 이벤트를 발생시키는 것 이상을 수행 할 수 없습니다. 이 경우 Schedule으로 생성되며 비공개 회원을 통해 모든 배우가 사용할 수 있습니다. SomeOtherClass은 Foo의 Schedule.ScheduleChangeNotifier에 대한 참조를 얻을 수 있습니다. 목록이 변경되면 Schedule은 이벤트를 발생시키는 메소드를 호출하고 Foo는 관련되지 않습니다.

이 패턴은 일반적으로 EventBus라고 불리지 만 브로드 캐스트 - 수신기 설정으로 생각할 수 있습니다. 일정은 클래스를 사용하여 알림을 브로드 캐스트하고 다른 사람들은이를 이벤트로 수신하기 위해이를 사용합니다. 그렇지 않으면 두 배우가 서로에 대해 알 필요가 없을 때 유용합니다.

예는 Fizz.Blorg에서 무언가에 대해 알 필요 Foo.Bar 다음과 같습니다 BarBar 버스/통지 객체를 받고 넘어 Fizz 또는 Foo를 포함하지 않고 그 이벤트를 수신 할 수있다.

이벤트를 버블 링하는 것보다 덜 일반적이지만 때로는 매우 유용합니다. 보통 그것이 대답 인 것처럼 보일지라도, 나는 물건이 단순화 될 수 있는지보기 위해 디자인을 재검토하려고 노력한다.

0

List(Of)은 기본적으로이 기능을 제공하지 않습니다.

IList(Of)의 고유 한 구현을 만들고 원하는 이벤트를 구현하거나 BindingList(Of) 또는 ObservableCollection(Of)과 같은 기존 컬렉션을 사용할 수 있습니다.

관련 문제