Преобразование строки обработчика события CollectionChanged из C # в VB.net - PullRequest
3 голосов
/ 27 октября 2011

Я использовал developerfusion C # для преобразования в VB , чтобы конвертировать проект Брэда Смита 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 должен быть адрес метода.

Я в тупике, здесь. Чего мне не хватает?

Ответы [ 3 ]

2 голосов
/ 27 октября 2011

Я не верю, что 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 # в ваш проект VB.NET, содержащий код C #, или создать код C # для использования в приложении VB.NET.

Чтобы ответить на ваш вопрос о value.Nodes.CollectionChanged += CollectionChanged;, этообъединение делегатов CollectionChanged родительского узла с текущим узлом.По сути, каждое изменение всего дерева будет вызывать обработчики событий каждого дочернего элемента, поднимаясь вверх по дереву.Подобное объединение делегатов создает многоадресный делегат, а в C # объединение многоадресных делегатов через события так же просто, как + =.Однако в VB.NET кажется, что AddHandler не преобразует события в делегаты.

1 голос
/ 27 октября 2011

Здесь вам не хватает определения обратного вызова, который затем делегирует событие в соответствии с этим:

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))
1 голос
/ 27 октября 2011

Кажется, что последние две строки заставляют новый дочерний узел подписаться на событие CollectionChanged контейнера, а затем запускают событие (потому что новый дочерний узел был записан в коллекцию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...