DCSIMG
ObservableDictionary(Of TKey, TValue) - VB.NET - Shimmy on .NET

ObservableDictionary(Of TKey, TValue) - VB.NET

Here you go with an ObservableDictionary<TKey, TValue> that will allow you to create a UI connected to a dictionary, 
getting notified on dictionary item-changes.
This one supports an AddRange method that allows adding a bulk of items (will throw for existing keys) without notifying for each item 
(opposed to ObservableCollection<T> that doesn't).
To the C# version.
NOTE: This class is not tested and thus not meant to be used in a multi-threaded application.
HTH, Shimmy

Imports System.ComponentModel
Imports System.Collections.Specialized

Public Class ObservableDictionary(Of TKeyTValue)
  Implements IDictionary(Of TKeyTValue), INotifyPropertyChangedINotifyCollectionChanged

#Region "Constructors"
  Public Sub New()
    m_Dictionary = New Dictionary(Of TKeyTValue)
  End Sub
  Public Sub New(ByVal dictionary As IDictionary(Of TKeyTValue))
    m_Dictionary = New Dictionary(Of TKeyTValue)(dictionary)
  End Sub
  Public Sub New(ByVal comparer As IEqualityComparer(Of TKey))
    m_Dictionary = New Dictionary(Of TKeyTValue)(comparer)
  End Sub
  Public Sub New(ByVal capacity As Integer)
    m_Dictionary = New Dictionary(Of TKeyTValue)(capacity)
  End Sub
  Public Sub New(ByVal dictionary As IDictionary(Of TKeyTValue), ByVal comparer As IEqualityComparer(Of TKey))
    m_Dictionary = New Dictionary(Of TKeyTValue)(dictionarycomparer)
  End Sub
  Public Sub New(ByVal capacity As IntegerByVal comparer As IEqualityComparer(Of TKey))
    m_Dictionary = New Dictionary(Of TKeyTValue)(capacitycomparer)
  End Sub
#End Region 'Constructors

#Region "Fields"

  Private Const CountString As String = "Count"
Private Const IndexerName As String = "Item[]"
Private Const KeysName As String = "Keys"
Private Const ValuesName As String = "Values"
  Public Event PropertyChanged(ByVal sender As ObjectByVal e As PropertyChangedEventArgs) _
    Implements INotifyPropertyChanged.PropertyChanged
  Public Event CollectionChanged(ByVal sender As ObjectByVal e As NotifyCollectionChangedEventArgs) _
    Implements INotifyCollectionChanged.CollectionChanged
  Private m_Dictionary As IDictionary(Of TKeyTValue)

#End Region 'Fields

  Protected ReadOnly Property Dictionary As IDictionary(Of TKeyTValue)
    Get
      Return m_Dictionary
    End Get
  End Property

  Public Overloads Sub Clear() Implements ICollection(Of KeyValuePair(Of TKeyTValue)).Clear

    If Dictionary.Count > 0 Then
 OnCollectionChanged()
  End If
  End Sub

  Public Sub Add(ByVal item As KeyValuePair(Of TKeyTValue)) Implements ICollection(Of KeyValuePair(Of TKeyTValue)).Add
    Insert(item.Keyitem.ValueTrue)
  End Sub
  Public Sub Add(ByVal key As TKeyByVal value As TValueImplements IDictionary(Of TKeyTValue).Add
    Insert(keyvalueTrue)
  End Sub
  Public Sub AddRange(ByVal items As IDictionary(Of TKeyTValue))
    If items Is Nothing Then Throw New ArgumentNullException("items")
    If items.Count > 0 Then
      If Dictionary.Count > 0 Then
        If items.Keys.Any(Function(keyDictionary.ContainsKey(key)) Then
          Throw New ArgumentException("An item with the same key has already been added.")


        Else
For Each i In items
           Dictionary.Add(i)
         Next
End If

      Else
        m_Dictionary = New Dictionary(Of TKeyTValue)(items)

      End If
      OnCollectionChanged(NotifyCollectionChangedAction.Additems.ToArray)
    End If
  End Sub

  Private Function Remove(ByVal item As KeyValuePair(Of TKeyTValue)) As Boolean _
    Implements ICollection(Of KeyValuePair(Of TKeyTValue)).Remove
    Return Remove(item.Key)
  End Function
  Public Function Remove(ByVal key As TKeyAs Boolean Implements IDictionary(Of TKeyTValue).Remove
    If key Is Nothing Then Throw New ArgumentNullException("key")

    Dim item As TValue
    Dictionary.TryGetValue(keyitem)
    Dim removed = Dictionary.Remove(key)
    If removed Then OnCollectionChanged() 'FieldsNotifyCollectionChangedAction.Remove, New KeyValuePair(Of TKey, TValue)(key, item)
    Return removed
  End Function
  Default Public Property Item(ByVal key As TKeyAs TValue Implements IDictionary(Of TKeyTValue).Item
    Get
      Return Dictionary(key)
    End Get
    Set(ByVal value As TValue)
      Insert(keyvalueFalse)
    End Set
  End Property

  Private Sub Insert(ByVal key As TKeyByVal value As TValueByVal add As Boolean)
    If key Is Nothing Then Throw New ArgumentNullException("key")

    Dim item As TValue
    If Dictionary.TryGetValue(keyitemThen
      If add Then Throw New ArgumentException("An item with the same key has already been added.")
      If Equals(itemvalueThen Exit Sub
      Dictionary(key) = value
OnCollectionChanged(NotifyCollectionChangedAction.ReplaceNew KeyValuePair(Of TKeyTValue)(keyvalue),
                          New KeyValuePair(Of TKeyTValue)(keyitem))
    Else
Dictionary(key) = value
     OnCollectionChanged(NotifyCollectionChangedAction.AddNew KeyValuePair(Of TKeyTValue)(keyvalue))
    End If
  End Sub

#Region "ReadOnly methods and properties"

  Public Overloads Sub CopyTo(ByVal array() As KeyValuePair(Of TKeyTValue), ByVal arrayIndex As Integer) _
    Implements ICollection(Of KeyValuePair(Of TKeyTValue)).CopyTo
    Dictionary.CopyTo(arrayarrayIndex)
  End Sub

  Public Overloads ReadOnly Property Count As Integer Implements ICollection(Of KeyValuePair(Of TKeyTValue)).Count
    Get
      Return Dictionary.Count
    End Get
  End Property

  Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of KeyValuePair(Of TKeyTValue)).IsReadOnly
    Get
      Return Dictionary.IsReadOnly
    End Get
  End Property

  Public ReadOnly Property Keys As ICollection(Of TKeyImplements IDictionary(Of TKeyTValue).Keys
    Get
      Return Dictionary.Keys
    End Get
  End Property
  Public ReadOnly Property Values As ICollection(Of TValueImplements IDictionary(Of TKeyTValue).Values
    Get
      Return Dictionary.Values
    End Get
  End Property

  Public Function Contains(ByVal item As KeyValuePair(Of TKeyTValue)) As Boolean _
    Implements ICollection(Of KeyValuePair(Of TKeyTValue)).Contains
    Return Dictionary.Contains(item)
  End Function
  Public Function ContainsKey(ByVal key As TKeyAs Boolean Implements IDictionary(Of TKeyTValue).ContainsKey
    Return Dictionary.ContainsKey(key)
  End Function
  Public Function ContainsValue(ByVal value As TValueAs Boolean
    Return Dictionary.Values.Contains(value)
  End Function

  Public Function TryGetValue(ByVal key As TKeyByRef value As TValueAs Boolean _
    Implements IDictionary(Of TKeyTValue).TryGetValue
    Return Dictionary.TryGetValue(keyvalue)
  End Function

  Public Overloads Function GetEnumerator() As IEnumerator(Of KeyValuePair(Of TKeyTValue)) _
    Implements IEnumerable(Of KeyValuePair(Of TKeyTValue)).GetEnumerator
    Return Dictionary.GetEnumerator
  End Function
  Private Function GetIEnumerableEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
    Return DirectCast(DictionaryIEnumerable).GetEnumerator
  End Function

  Private Sub OnPropertyChanged()
    OnPropertyChanged(CountString)
OnPropertyChanged(IndexerName)
OnPropertyChanged(KeysName)
OnPropertyChanged(ValuesName)
  End Sub

  Protected Overridable Sub OnPropertyChanged(ByVal propertyName As String)
    RaiseEvent PropertyChanged(MeNew PropertyChangedEventArgs(propertyName))
  End Sub

  Private Sub OnCollectionChanged()
    OnPropertyChanged()
    RaiseEvent CollectionChanged(MeNew NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
  End Sub

  Private Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedAction,
                                  ByVal changedItem As KeyValuePair(Of TKeyTValue))
    OnPropertyChanged()
    RaiseEvent CollectionChanged(MeNew NotifyCollectionChangedEventArgs(actionchangedItem))
  End Sub

  Private Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedActionByVal newItem As KeyValuePair(Of TKeyTValue),
                                  ByVal oldItem As KeyValuePair(Of TKeyTValue))
    OnPropertyChanged()
    RaiseEvent CollectionChanged(MeNew NotifyCollectionChangedEventArgs(actionnewItemoldItem))
  End Sub

  Private Sub OnCollectionChanged(ByVal action As NotifyCollectionChangedActionByVal newItems As IList)
    OnPropertyChanged()
    RaiseEvent CollectionChanged(MeNew NotifyCollectionChangedEventArgs(actionnewItems))
  End Sub


#End Region 'ReadOnly methods and properties
End Class
Published Thursday, December 02, 2010 8:17 AM by Shimmy

Comments

No Comments

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems