将CollectionChanged事件处理程序行从C#转换为VB.net

时间:2011-10-27 09:58:19

标签: c# .net vb.net events

我已经使用developerfusion C# to VB conversion tool来转换Brad Smith's ComboTreeBox项目而且我遇到了麻烦,对我来说是相当正常的,而且C#-to-VB转换是一个事件处理程序。

IList(Of ComboTreeNode).Item的接口实现中有这个C#代码:

#region IList<ComboTreeNode> Members

public ComboTreeNode this[int index] {
    get {
        return innerList[index];
    }
    set {
        ComboTreeNode oldItem = innerList[index];
        innerList[index] = value;
        value.Parent = node;
        value.Nodes.CollectionChanged += CollectionChanged;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem));
    }
}

转换为

Public Default Property Item(index As Integer) As ComboTreeNode Implements IList(Of ComboTreeNode).Item, IList.Item
    Get
        Return innerList(index)
    End Get
    Set
        Dim oldItem As ComboTreeNode = innerList(index)
        innerList(index) = value
        value.Parent = node
        value.Nodes.CollectionChanged += CollectionChanged
        OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem))
    End Set
End Property

我在Set方法的最后两行收到错误,坦率地说,我不明白在那里做了什么。从我有限的C#事件知识来看,似乎是将事件处理程序添加回事件本身,这让我完全迷失了。

AddHandler value.Nodes.CollectionChanged, AddressOf CollectionChanged进行天真转换只会提醒您AddHandler的第二个参数需要是方法地址。

我在这里难过。我错过了什么?

3 个答案:

答案 0 :(得分:2)

我不相信VB.NET有任何方法来组合这样的事件,所以你可能不得不调整它以使用多播委托。我不会测试这段代码,但我们可以随时调试它。

首先,在ComboTreeNodeCollection中,将CollectionChanged事件更改为Public CollectionChanged As NotifyCollectionChangedEventHandler

对于所有value.Nodes.CollectionChanged += CollectionChanged,请将其更改为value.Nodes.CollectionChanged = [Delegate].Combine(value.Nodes.CollectionChanged, CollectionChanged) 对于 - =,请使用value.Nodes.CollectionChanged = [Delegate].Remove(value.Nodes.CollectionChanged, CollectionChanged)

最后(希望如此),对于Protected Overridable Sub OnCollectionChanged,将CollectionChanged(Me, e)(或看起来更新)更改为CollectionChanged.Invoke(Me, e)

哦,您可能想要添加替换AddHandler和RemoveHandler的方法。实际上,我只是想知道您可以在哪里创建一个自定义事件,该事件组合并从委托中删除;您仍然需要实现上面的代码,但是,当您或其他用户想要使用该事件时,他们将能够正常添加和删除。

这显然不是首选,但是,如果有某种方式我不记得得到一个事件的代表,那将是首选。另一个想法是将C#项目添加到包含C#代码的VB.NET项目中,或者构建用于VB.NET应用程序的C#代码。

要回答有关value.Nodes.CollectionChanged += CollectionChanged;的问题,它会将父节点的CollectionChanged委托与当前节点组合在一起。实际上,对整个树的每一次更改都会引发每个孩子的事件处理程序,从而向上移动树。像这样的委托的组合创建了一个多播委托,并且在C#中,通过事件组合多播委托就像+ =一样简单。但是,在VB.NET中,似乎AddHandler不会将事件转换为委托。

答案 1 :(得分:1)

最后两行似乎导致新的子节点订阅容器的CollectionChanged事件,然后触发事件(因为新的子节点被写入集合)。

答案 2 :(得分:1)

你在这里缺少的是回调的定义,然后按照以下方式委托回事件:

Public Sub OnCollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
   RaiseEvent CollectionChanged(Me, e)
End Sub

另外,请确保添加事件对象:

Public Event CollectionChanged As NotifyCollectionChangedEventHandler

然后你的最后几行可能是

 AddHandler value.Nodes.CollectionChanged, AddressOf OnCollectionChanged
 OnCollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add))