我已经使用developerfusion C# to VB conversion tool转换了Brad Smith's ComboTreeBox项目,并且遇到了麻烦,这对我和从C#到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的第二个参数必须是方法地址。

我被困在这里。我想念什么?

最佳答案

我不相信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不会将事件转换为委托。

10-08 14:08