I've been trying to gea DataGridView to bind to an IList(Of T)
implementation. Basically, I have a fixed size list where the members
can be changed, but new members can not leave and old members cannot
be deleted.
To isolate the problem I made a simple project with a simple class
which implements IList(Of T). The implementation raises
NotSupportedException for anything that would not be supported
(Adding,deleting, clear, insert at, etc.). I'm 100% positive that the
problem lies in my IList(Of T) implementation, but I don't know what I
am doing wrong. I say "100%" because if I expose the list which is
stored internally, that exposed list populates the DGV just fine.
So, on my form I have a DataGridView (topMyDGVMyData) and a single
button. When the button is pressed, the following code is executed:
'Code
Start____________________________________________________________________
Private Sub topButtonFill_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles topButtonFill.Click
Me.topDGVMyData.AutoGenerateColumns = False
Me.topDGVMyData.AutoSize = True
Me.topDGVMyData.DataSource = oMySource.ExposedList
Me.topDGVMyData.Columns.Clear()
Dim oCol As DataGridViewColumn = Nothing
oCol = New DataGridViewTextBoxColumn
oCol.DataPropertyName = "DatumName"
oCol.Name = "The Name"
Me.topDGVMyData.Columns.Add(oCol)
oCol = New DataGridViewTextBoxColumn
oCol.DataPropertyName = "DatumValue"
oCol.Name = "The Value"
Me.topDGVMyData.Columns.Add(oCol)
End Sub
'Code
End______________________________________________________________________
And of course, I have my simple classes:
'Code
Start____________________________________________________________________
'Simple datum for MyBindingSource with a readonly property and a
'readwrite property.
Public Class MyDatum
Implements IComparable(Of MyDatum)
Implements IEquatable(Of MyDatum)
Private _strName As String
Private _dblValue As Double
Public Sub New(ByVal p_strName As String, ByVal p_dblValue As
Double)
_strName = p_strName
_dblValue = p_dblValue
End Sub
Private Sub New()
End Sub
Public ReadOnly Property DatumName() As String
Get
Return _strName
End Get
End Property
Public Property DatumValue() As Double
Get
Return _dblValue
End Get
Set(ByVal value As Double)
_dblValue = value
End Set
End Property
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is MyDatum Then
Return Me.Equals(CType(obj, MyDatum))
Else
Return False
End If
End Function
Public Overloads Function Equals(ByVal other As MyDatum) As
Boolean Implements System.IEquatable(Of MyDatum).Equals
Return Me.DatumName = other.DatumName And Me.DatumValue =
other.DatumValue
End Function
Public Overloads Function CompareTo(ByVal other As MyDatum) As
Integer Implements System.IComparable(Of MyDatum).CompareTo
If Me.DatumName.CompareTo(other.DatumName) = 0 Then
Return Me.DatumValue.CompareTo(other.DatumValue)
Else
Return Me.DatumName.CompareTo(other.DatumName)
End If
End Function
Public Overrides Function ToString() As String
Return Me.DatumName & ": " & Me.DatumValue
End Function
End Class
'This implements IList(Of MyDatum) and acts as a fixed-size list.
'Implementation really just wraps around an internally stored list
'(exposed by Me.ExposedList).
Public Class MyBindingSource
Implements IList(Of MyDatum)
Private _oList As List(Of MyDatum)
Public ReadOnly Property ExposedList() As List(Of MyDatum)
Get
Return _oList
End Get
End Property
Public Sub New()
Dim i As Integer = 0
_oList = New List(Of MyDatum)
For i = 0 To 10
_oList.Add(New MyDatum("Value #" & i, i))
Next
End Sub
Public Sub Add(ByVal item As MyDatum) Implements
System.Collections.Generic.ICollection(Of MyDatum).Add
Throw New NotSupportedException
End Sub
Public Sub Clear() Implements
System.Collections.Generic.ICollection(Of MyDatum).Clear
Throw New NotSupportedException
End Sub
Public Function Contains(ByVal item As MyDatum) As Boolean
Implements System.Collections.Generic.ICollection(Of MyDatum).Contains
Return _oList.Contains(item)
End Function
Public Sub CopyTo(ByVal array() As MyDatum, ByVal arrayIndex As
Integer) Implements System.Collections.Generic.ICollection(Of
MyDatum).CopyTo
_oList.CopyTo(array, arrayIndex)
End Sub
Public ReadOnly Property Count() As Integer Implements
System.Collections.Generic.ICollection(Of MyDatum).Count
Get
Return _oList.Count
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean Implements
System.Collections.Generic.ICollection(Of MyDatum).IsReadOnly
Get
Return False
End Get
End Property
Public Function Remove(ByVal item As MyDatum) As Boolean
Implements System.Collections.Generic.ICollection(Of MyDatum).Remove
Throw New NotSupportedException
End Function
Public Function GetEnumerator() As
System.Collections.Generic.IEnumerator(Of MyDatum) Implements
System.Collections.Generic.IEnumerable(Of MyDatum).GetEnumerator
Return _oList.GetEnumerator
End Function
Public Function IndexOf(ByVal item As MyDatum) As Integer
Implements System.Collections.Generic.IList(Of MyDatum).IndexOf
Return _oList.IndexOf(item)
End Function
Public Sub Insert(ByVal index As Integer, ByVal item As MyDatum)
Implements System.Collections.Generic.IList(Of MyDatum).Insert
Throw New NotSupportedException
End Sub
Default Public Property Item(ByVal index As Integer) As MyDatum
Implements System.Collections.Generic.IList(Of MyDatum).Item
Get
Return _oList.Item(index)
End Get
Set(ByVal value As MyDatum)
_oList.Item(index) = value
End Set
End Property
Public Sub RemoveAt(ByVal index As Integer) Implements
System.Collections.Generic.IList(Of MyDatum).RemoveAt
Throw New NotSupportedException
End Sub
Public Function GetEnumerator1() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return _oList.GetEnumerator
End Function
End Class
'Code
End______________________________________________________________________
As you can see from my MyDatum class, the DatumName property is read