I have a standard C# queue, declared like this:
private Queue<DeployJob> _solutionQueue = new Queue<DeployJob>();
Now I want to bind this queue to an DataGridView, which is placed inside a winform. With "bind" i mean that everytime i dequeue
or enqueue
an item from the queue the DataGridView
gets updated (so that it always represents the state of the queue).
I have tried to bind it this way:
jobGridView.DataSource = _solutionQueue;
But it doesnt work, even if I use the update
or refresh
methods. If you need more code, please feel free to ask :)
According to MSDN , the DataGridView.DataSource
must implement one of the following interfaces:
IList
IListSource
IBindingList
IBindingListView
The Queue<T>
class implements parent interfaces of IList
, including IEnumerable
and ICollection
, but not IList
itself.
One suggestion is to use LINQ to create a List<DeployJob>
from the queue and bind like so:
using System.Linq;
//code
jobGridView.DataSource = _solutionQueue.ToList();
You would want to make sure and handle any events that update/modify the queue, and re-bind the DataGridView to a newly created List
I created a generic queue type that makes a queue observable and a derived type that makes this new queue behave like a list and a binding list. This works for read only features of a datagridview. You would need to extend further if you need additional functionality.
Observable concurrent queue:
Imports System.Collections.Concurrent
Imports System.Collections.Specialized
Public Class ObservableConcurrentQueue(Of T)
Inherits ConcurrentQueue(Of T)
Implements INotifyCollectionChanged
Public Event CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs) Implements INotifyCollectionChanged.CollectionChanged
Private Sub OnCollectionChanged(ByVal args As NotifyCollectionChangedEventArgs)
RaiseEvent CollectionChanged(Me, args)
End Sub
Public Shadows Sub Enqueue(ByVal item As T)
MyBase.Enqueue(item)
OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item))
End Sub
Public Shadows Function TryDequeue(ByRef result As T) As Boolean
If Not MyBase.TryDequeue(result) Then
Return False
End If
OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, result))
Return True
End Function
End Class
Wrap it further to behave like a list and abindinglist:
Imports System.Linq
Imports System.ComponentModel
Imports System.Collections.Specialized
Imports System.Linq.Expressions
Public Class ObservableConcurrentQueueList(Of T)
Inherits ObservableConcurrentQueue(Of T)
Implements IList(Of T), IBindingList
Public Sub Clear()
Dim item As T
While (Not IsEmpty())
MyBase.TryDequeue(item)
End While
End Sub
#Region "IList Implementation"
Public Sub Add1(item As T) Implements ICollection(Of T).Add
MyBase.Enqueue(item)
End Sub
Protected Sub Clear1() Implements ICollection(Of T).Clear
Clear()
End Sub
Protected Function Contains1(item As T) As Boolean Implements ICollection(Of T).Contains
Return MyBase.Contains(item)
End Function
Protected Sub CopyTo1(array() As T, arrayIndex As Integer) Implements ICollection(Of T).CopyTo
MyBase.CopyTo(array, arrayIndex)
End Sub
Protected ReadOnly Property Count1 As Integer Implements ICollection(Of T).Count
Get
Return MyBase.Count
End Get
End Property
Protected ReadOnly Property IsReadOnly1 As Boolean Implements ICollection(Of T).IsReadOnly
Get
Return True
End Get
End Property
Protected Function Remove1(item As T) As Boolean Implements ICollection(Of T).Remove
Throw New NotImplementedException
End Function
Protected Function IndexOf1(item As T) As Integer Implements IList(Of T).IndexOf
Return Me.ToList.IndexOf(item)
End Function
Protected Sub Insert1(index As Integer, item As T) Implements IList(Of T).Insert
Throw New NotImplementedException
End Sub
Protected Property Item1(index As Integer) As T Implements IList(Of T).Item
Get
Return Me.ToList.Item(index)
End Get
Set(value As T)
Throw New NotImplementedException
End Set
End Property
Protected Sub RemoveAt1(index As Integer) Implements IList(Of T).RemoveAt
Throw New NotImplementedException
End Sub
#End Region
#Region "IBindList Implementation"
Protected Function Add2(value As Object) As Integer Implements IList.Add
'Throw New NotImplementedException
MyBase.Enqueue(value)
Return Nothing
End Function
Protected Sub Clear2() Implements IList.Clear
Clear()
End Sub
Protected Function Contains2(value As Object) As Boolean Implements IList.Contains
Return MyBase.Contains(value)
End Function
Protected Function IndexOf2(value As Object) As Integer Implements IList.IndexOf
Return Me.ToList.IndexOf(value)
End Function
Protected Sub Insert2(index As Integer, value As Object) Implements IList.Insert
Throw New NotImplementedException
End Sub
Protected ReadOnly Property IsFixedSize2 As Boolean Implements IList.IsFixedSize
Get
Return False
End Get
End Property
Protected ReadOnly Property IsReadOnly2 As Boolean Implements IList.IsReadOnly
Get
Return True
End Get
End Property
Protected Overloads Property Item2(index As Integer) As Object Implements IList.Item
Get
Return Me.ToList.Item(index)
End Get
Set(value As Object)
Throw New NotImplementedException
End Set
End Property
Protected Sub Remove2(value As Object) Implements IList.Remove
Throw New NotImplementedException
End Sub
Protected Sub RemoveAt2(index As Integer) Implements IList.RemoveAt
Throw New NotImplementedException
End Sub
Protected Sub AddIndex2([property] As PropertyDescriptor) Implements IBindingList.AddIndex
End Sub
Protected Function AddNew2() As Object Implements IBindingList.AddNew
Throw New NotImplementedException
End Function
Protected ReadOnly Property AllowEdit2 As Boolean Implements IBindingList.AllowEdit
Get
Return False
End Get
End Property
Protected ReadOnly Property AllowNew2 As Boolean Implements IBindingList.AllowNew
Get
Return False
End Get
End Property
Protected ReadOnly Property AllowRemove2 As Boolean Implements IBindingList.AllowRemove
Get
Return False
End Get
End Property
Protected Sub ApplySort2([property] As PropertyDescriptor, direction As ListSortDirection) Implements IBindingList.ApplySort
Throw New NotImplementedException
End Sub
Protected Function Find2([property] As PropertyDescriptor, key As Object) As Integer Implements IBindingList.Find
Throw New NotImplementedException
Return Nothing
End Function
Protected ReadOnly Property IsSorted2 As Boolean Implements IBindingList.IsSorted
Get
Return False
End Get
End Property
Protected Event ListChanged2(sender As Object, e As ListChangedEventArgs) Implements IBindingList.ListChanged
Protected Sub RemoveIndex2([property] As PropertyDescriptor) Implements IBindingList.RemoveIndex
Throw New NotImplementedException
End Sub
Protected Sub RemoveSort2() Implements IBindingList.RemoveSort
'Throw New NotImplementedException
End Sub
Protected ReadOnly Property SortDirection2 As ListSortDirection Implements IBindingList.SortDirection
Get
'Throw New NotImplementedException
End Get
End Property
Protected ReadOnly Property SortProperty2 As PropertyDescriptor Implements IBindingList.SortProperty
Get
Throw New NotImplementedException
Return Nothing
End Get
End Property
Protected ReadOnly Property SupportsChangeNotification2 As Boolean Implements IBindingList.SupportsChangeNotification
Get
Return True
End Get
End Property
Protected ReadOnly Property SupportsSearching2 As Boolean Implements IBindingList.SupportsSearching
Get
Return False
End Get
End Property
Protected ReadOnly Property SupportsSorting2 As Boolean Implements IBindingList.SupportsSorting
Get
Return False
End Get
End Property
#End Region
End Class
Use it in a form:
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.AutoGenerateColumns = True
Me.DataGridView1.DataSource = MyObservableQueueList
AddHandler MyObservableQueueList.CollectionChanged, AddressOf UpdateGrid
End Sub
Private Sub UpdateGrid(sender As Object, e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
Me.MyObservableQueueList.DataSource = Nothing
Me.MyObservableQueueList.DataSource = _AlarmHistory
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
RemoveHandler MyObservableQueueList.CollectionChanged, AddressOf UpdateGrid
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.