WPF: Что мне нужно реализовать, чтобы сделать привязанный расширенный IList (of T)? - PullRequest
3 голосов
/ 15 марта 2011

Я расширяю IList, чтобы я мог отслеживать изменения, внесенные в список (обновления, вставки и удаления).
Все в порядке, но я не могу связать с ним какие-либо ItemsControl.

Public Class TrackedList(Of T)
    Implements IList(Of T), INotifyCollectionChanged

    Public Sub New(Lista As IList(Of T))
        m_inner = Lista
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
    End Sub

    Private m_inner As IList(Of T)
    Public ReadOnly Property Inner() As IList(Of T)
        Get
            If m_inner Is Nothing Then
                m_inner = New List(Of T)()
            End If
            Return m_inner
        End Get
    End Property

    Private m_Updates As IList(Of T)
    Public ReadOnly Property Updates() As IList(Of T)
        Get
            If m_Updates Is Nothing Then
                m_Updates = New List(Of T)()
            End If
            Return m_Updates
        End Get
    End Property

    Private m_Inserts As IList(Of T)
    Public ReadOnly Property Inserts() As IList(Of T)
        Get
            If m_Inserts Is Nothing Then
                m_Inserts = New List(Of T)()
            End If
            Return m_Inserts
        End Get
    End Property

    Private m_Deletes As IList(Of T)
    Public ReadOnly Property Deletes() As IList(Of T)
        Get
            If m_Deletes Is Nothing Then
                m_Deletes = New List(Of T)()
            End If
            Return m_Deletes
        End Get
    End Property

    'Propietary methods'
    Public Sub ItemUpdated(ByVal item As T)
        If Not Updates.Contains(item) Then Updates.Add(item)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace))
    End Sub

    Public Sub FlushChanges()
        m_Updates = Nothing
        m_Inserts = Nothing
        m_Updates = Nothing
    End Sub


    Public Sub Add(ByVal item As T) Implements System.Collections.Generic.ICollection(Of T).Add
        Inner.Add(item)
        Inserts.Add(item)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add))
    End Sub

    Public Sub Clear() Implements System.Collections.Generic.ICollection(Of T).Clear
        If m_inner IsNot Nothing Then
            Inner.Clear()
        End If
    End Sub

    Public Function Contains(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Contains
        Return Inner.Contains(item)
    End Function

    Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of T).CopyTo
        Inner.CopyTo(array, arrayIndex)
    End Sub

    Public ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of T).Count
        Get
            Return Inner.Count
        End Get
    End Property

    Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of T).IsReadOnly
        Get
            Return Inner.IsReadOnly
        End Get
    End Property

    Public Function Remove(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Remove
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove))
        Deletes.Add(item)
        Return Inner.Remove(item)

    End Function


    Public Function IndexOf(ByVal item As T) As Integer Implements System.Collections.Generic.IList(Of T).IndexOf
        Return Inner.IndexOf(item)
    End Function

    Public Sub Insert(ByVal index As Integer, ByVal item As T) Implements System.Collections.Generic.IList(Of T).Insert
        Inserts.Add(item)
        Inner.Insert(index, item)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add))
    End Sub

    Default Public Property Item(ByVal index As Integer) As T Implements System.Collections.Generic.IList(Of T).Item
        Get
            Return Inner(index)
        End Get
        Set(ByVal value As T)
            Inner(index) = value
        End Set
    End Property

    Public Sub RemoveAt(ByVal index As Integer) Implements System.Collections.Generic.IList(Of T).RemoveAt
        Deletes.Add(Inner(index))
        Inner.RemoveAt(index)
        RaiseEvent CollectionChanged(Me, New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove))
    End Sub

    Public Function GetEnumerator1() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return Inner.GetEnumerator()
    End Function

    Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return DirectCast(Inner, IEnumerable).GetEnumerator()
    End Function


    Public Event CollectionChanged(sender As Object, e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Implements System.Collections.Specialized.INotifyCollectionChanged.CollectionChanged

End Class

Что мне нужно сделать, чтобы сделать список привязываемым?

Ответы [ 2 ]

4 голосов
/ 15 марта 2011

Если вы не можете просто наследовать от ObservableCollection , вы, вероятно, действительно хотите реализовать INotifyCollectionChanged .

0 голосов
/ 16 марта 2011

Проблема не в классе, ей даже не нужно реализовывать INotifyCollectionChanged

Проблема была в промежуточном контроле, который имеет DependencyProperty для преодоления привязки

Public Shared ReadOnly ItemsProperty As DependencyProperty = _
    DependencyProperty.Register("Items", GetType(IList), GetType(MainWindowViewModel))

Public Property Items As IList
    Set(ByVal value As IList)
        SetValue(ItemsProperty, value)
    End Set
    Get
        Return DirectCast(GetValue(ItemsProperty), IList)
    End Get
End Property

Оказывается, что изменение свойства зависимости на IEnumerable решило проблему.

...