2010-02-01 100 views
2

我正在查看this博客,并且我正在尝试将该片段翻译为VB。需要帮助翻译C#到VB

我遇到困难,这条线:

NotifyCollectionChangedEventHandler handlers = this.CollectionChanged; 

注:CollectionChanged就是这样的一个事件(“本”是ObservableCollection<T>的覆盖)。

回答

3

提高事件,OnCollectionChanged应该可以正常工作。如果你想查询它,你必须获得更多的虐待和使用反射(对不起,例如是C#,但应该是几乎相同的 - 我没有使用任何特定语言的功能在这里):

NotifyCollectionChangedEventHandler handler = (NotifyCollectionChangedEventHandler) 
    typeof(ObservableCollection<T>) 
    .GetField("CollectionChanged", BindingFlags.Instance | BindingFlags.NonPublic) 
    .GetValue(this); 

等瞧;处理程序或处理程序(通过GetInvocationList())。

所以基本上在你的榜样(关于该职位),用途:

Protected Overrides Sub OnCollectionChanged(e As NotifyCollectionChangedEventArgs) 
    If e.Action = NotifyCollectionChangedAction.Add AndAlso e.NewItems.Count > 1 Then 
     Dim handler As NotifyCollectionChangedEventHandler = GetType(ObservableCollection(Of T)).GetField("CollectionChanged", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me) 
     For Each invocation In handler.GetInvocationList 
      If TypeOf invocation.Target Is ICollectionView Then 
       DirectCast(invocation.Target, ICollectionView).Refresh() 
      Else 
       MyBase.OnCollectionChanged(e) 
      End If 
     Next 
    Else 
     MyBase.OnCollectionChanged(e) 
    End If 
End Sub 
+0

@Mark,你是赢家,大好时光! – Shimmy 2010-02-01 22:11:05

2

从字面上看,它应该像

Dim handlers As NotifyCollectionChangedEventHandler = AddressOf Me.CollectionChanged 

(不能告诉,因为我不知道确切的类型)

但请注意,您在使用提高在VB事件RaiseEvent

+0

这仅'CollectionChanged'是用户,而不是事件处理程序(它可能是),但在这种情况下,您的作品第二句适用。 – 2010-02-01 19:20:55

+0

它根本不起作用,一年前我尝试过。 AddressOf只需要一个方法名称。 – Shimmy 2010-02-01 19:29:59

+0

@Shimmy:给出你的信息,这是一个有效的猜测。 'AddressOf'在这个确切的上下文中起作用。没有其他直接翻译你想要的。 – 2010-02-01 19:33:01

2

杜。在已经终于看到和阅读的博客张贴您链接,这里的答案:

在VB中,你需要声明一个自定义事件覆盖RaiseEvent机制。在最简单的情况下,这看起来是这样的:

Private m_MyEvent As EventHandler 

Public Custom Event MyEvent As EventHandler 
    AddHandler(ByVal value as EventHandler) 
     m_MyEvent = [Delegate].Combine(m_MyEvent, value) 
    End AddHandler 

    RemoveHandler(ByVal value as EventHandler) 
     m_MyEvent = [Delegate].Remove(m_MyEvent, value) 
    End RemoveHandler 
    RaiseEvent(sender as Object, e as EventArgs) 
     Dim handler = m_MyEvent 

     If handler IsNot Nothing Then 
      handler(sender, e) 
     End If 
    End RaiseEvent 
End Event 

在你的情况下,RaiseEvent例程是稍微有点复杂,以反映额外的逻辑,但要点是一样的。

+0

@Shimmy:我回滚了你的编辑;它实际上引入了一个令人讨厌的多线程错误。复制事件处理程序**是重要的! (和'Shadows'在那里没有任何地方。) – 2010-02-01 20:12:17

+0

我怎样才能进入基地事件呢? – Shimmy 2010-02-01 20:21:04

+0

@Shimmy:你不能。无论出于何种原因,任何类都不能直接访问其基类事件。 .NET只是不允许。 – 2010-02-01 21:05:29