Свойство тега ListViewItem ссылается на дубликат объекта, а не на исходный - PullRequest
0 голосов
/ 05 июня 2019

У меня есть FooCollection(of FooObject). Я заполняю ListView с ListViewItems:

Sub PopulateListView()
    For Each MyFoo as FooObject in FooCollection
        Dim MyItem as New ListViewItem(MyFoo.Name)
        MyItem.Tag=MyFoo
        ListView1.Items.Add(MyItem)
    Next
End Sub

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

Sub MyEvent() Handles ListView1.DoubleClick
    Dim ActiveFoo as FooObject = ListView1.FocusedItem.Tag
    ActiveFoo.Name = "SomethingNew"
End Sub

Если я тогда позвоню PopulateListView(), содержимое ListView не изменится (ListViewItem.text остается прежним).

Сценарий на самом деле более сложный, чем этот: он включает в себя сериализацию, а коллекция на самом деле является BindingList, которая обрабатывает ListChanged и сериализует / десериализует каждый раз, когда к коллекции обращаются. Я подозреваю, что проблема в этом, но прежде чем приступить к головной боли и рефакторингу, я хотел бы убедиться, что я не пропускаю что-то более простое.

C # ответы в порядке.


По запросу в комментариях дополнительная информация здесь:

Public Class FooObject
    Property Name as String
End Class


Public Class MyModel

    Property FooCollection As ICollection(Of FooObject)
        Get
            Dim SerializedObject as String = GetStringFromFile() 
            If SerializedObject = vbNullString Then
                _FooCollection = New BindingList(Of FooObject)
                _FooCollection.RaiseListChangedEvents = True
            Else
                Dim MyJSON As String = GetStringFromFile()
                _FooCollection= JsonConvert.DeserializeObject(Of BindingList(Of FooObject))(MyJSON)
            End If
            Return _FooCollection
        End Get
        Set(value As ICollection(Of FooObject))
            SetStringToFile(JsonConvert.SerializeObject(value))
        End Set
    End Property

    Private WithEvents _FooCollection As BindingList(Of FooObject)

    Private Sub _PopulatedExhibits_ListChanged(sender As Object, e As ListChangedEventArgs) Handles _FooCollection.ListChanged
        Dim MyBindingList As BindingList(Of FooObject) = sender
        SetStringToFile(JsonConvert.SerializeObject(MyBindingList))
    End Sub

End Class

1 Ответ

0 голосов
/ 05 июня 2019

Проблема была со ссылкой на объект, который теряется, если перед вызовом MyEvent.

был сделан другой вызов FooCollection.

Отдельные объекты коллекции можно заменить следующим образом. Однако это далеко не оптимально, поэтому любые улучшения приветствуются!

Partial Class MyModel

    Sub ReplaceObject(NewObjects As IEnumerable(Of FooObject))

        Dim TempCollection As New List(Of FooObject)(Me.FooCollection.ToList)

        For Each NewObject As FooObject In NewObjects 
            Dim ExistingObjectIndex As Integer = TempCollection.FindIndex(Function(p) p.UniqueId = NewObject.UniqueId)
            TempCollection.Item(ExistingObjectIndex) = NewObject 
        Next

        Me.FooCollection = TempCollection

    End Sub

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