【问题标题】:How can I bind a Queue to a DataGridView in C#/Winforms?如何在 C#/Winforms 中将队列绑定到 DataGridView?
【发布时间】:2012-02-12 19:42:52
【问题描述】:

我有一个标准的 C# 队列,声明如下:

private Queue<DeployJob> _solutionQueue = new Queue<DeployJob>();

现在我想将此队列绑定到一个 DataGridView,它位于一个 winform 中。 “绑定”是指每次我 dequeueenqueue 队列中的一个项目时,DataGridView 都会更新(因此它始终代表队列的状态)。

我试过这样绑定:

jobGridView.DataSource = _solutionQueue;

但它不起作用,即使我使用 updaterefresh 方法。如果您需要更多代码,请随时询问:)

【问题讨论】:

    标签: c# winforms data-binding datagridview queue


    【解决方案1】:

    根据MSDNDataGridView.DataSource 必须实现以下接口之一:

    • IList
    • IListSource
    • IBindingList
    • IBindingListView

    Queue&lt;T&gt;类实现了IList的父接口,包括IEnumerableICollection,但不包括IList本身。

    一个建议是使用 LINQ 从队列中创建一个List&lt;DeployJob&gt; 并像这样绑定:

    using System.Linq;    
    
    //code
    
    jobGridView.DataSource = _solutionQueue.ToList();
    

    您需要确保并处理任何更新/修改队列的事件,并将 DataGridView 重新绑定到新创建的列表

    【讨论】:

      【解决方案2】:

      我创建了一个使队列可观察的通用队列类型和一个使这个新队列表现得像一个列表和一个绑定列表的派生类型。这适用于 datagridview 的只读功能。如果您需要更多功能,则需要进一步扩展。

      可观察并发队列:

      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
      

      将其进一步包装成列表和绑定列表:

      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
      

      以表格形式使用:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-15
        • 2011-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-12
        • 2015-01-23
        相关资源
        最近更新 更多