I'm trying to modify the listview to have similar databinding behaviour to a datagrid with the added bonus of having the ability to group by a column in the datasource.
Below is the code I have developed so far. The only problem is that this code only binds to a datatable. I'd like to be able to bind to all the sources that a datagrid can (datatable, collection, etc).
I've spent alot of time searching on the net and all the examples I have found either show what I have already done, implement much more complex databinding than I need, or I can't make enough sense of the code to be able to modify it to suits my needs!
Could anyone point me to somewhere that will show me how to do what I need or give me a few pointers
Below is the code I have developed so far. The only problem is that this code only binds to a datatable. I'd like to be able to bind to all the sources that a datagrid can (datatable, collection, etc).
I've spent alot of time searching on the net and all the examples I have found either show what I have already done, implement much more complex databinding than I need, or I can't make enough sense of the code to be able to modify it to suits my needs!
Could anyone point me to somewhere that will show me how to do what I need or give me a few pointers
VB.NET:
Imports System.ComponentModel
Public Class GroupingListView
Inherits System.Windows.Forms.ListView
Private _dataSource As Object
Private _GroupBy As String
Private _GroupTitle As String
Private _GroupTag As String
Private DoGrouping As Boolean = False
Private DoGroupTitle As Boolean = False
Private DoGroupTag As Boolean = False
<TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design")> _
<Category("Data")> _
Public Property DataSource() As Object
Get
Return _dataSource
End Get
Set(ByVal value As Object)
_dataSource = value
End Set
End Property
<Category("Data")> _
Public Property GroupBy() As String
Get
Return _GroupBy
End Get
Set(ByVal value As String)
_GroupBy = value
End Set
End Property
<Category("Data")> _
Public Property GroupTitle() As String
Get
Return _GroupTitle
End Get
Set(ByVal value As String)
_GroupTitle = value
End Set
End Property
<Category("Data")> _
Public Property GroupTag() As String
Get
Return _GroupTag
End Get
Set(ByVal value As String)
_GroupTag = value
End Set
End Property
Public Sub DataBind()
If _dataSource Is Nothing Then
Console.WriteLine("No datasource to bind to")
Exit Sub
End If
If TypeOf _dataSource Is DataSet Then
If CType(_dataSource, DataSet).Tables.Count > 0 Then
_dataSource = CType(_dataSource, DataSet).Tables(0)
End If
End If
Dim lvwItem As New ListViewItem
Dim lvwGroup As New ListViewGroup
Dim Data As DataTable = CType(_dataSource, DataTable)
Dim NoColumns As Integer = Data.Columns.Count
For Each dc As DataColumn In Data.Columns
Me.Columns.Add(dc.ColumnName, 100)
If _GroupBy = dc.ColumnName Then
DoGrouping = True
End If
Next
For Each dc As DataColumn In Data.Columns
If _GroupTag = dc.ColumnName Then
'MsgBox("Column: " & dc.ColumnName & vbNewLine & "groupby: " & _GroupBy)
DoGroupTag = True
End If
Next
For Each dc As DataColumn In Data.Columns
If _GroupTitle = dc.ColumnName Then
DoGroupTitle = True
End If
Next
If DoGrouping = True Then
For Each dr As DataRow In Data.Rows
If lvwGroup.Name <> dr.Item(_GroupBy) Then
lvwGroup = New ListViewGroup()
lvwGroup.Name = dr.Item(_GroupBy)
If DoGroupTitle = True Then
lvwGroup.Header = dr.Item(_GroupTitle)
Else
lvwGroup.Header = dr.Item(_GroupBy)
End If
'If GroupTag property is a column that exists in the column
'then assign the property of this column to the tag property.
If DoGroupTag = True Then
lvwGroup.Tag = dr.Item(_GroupTag)
End If
Me.Groups.Add(lvwGroup)
lvwItem = New ListViewItem
lvwItem.Text = dr.Item(0)
For i As Integer = 1 To NoColumns - 1
lvwItem.SubItems.Add(dr.Item(i))
Next
Me.Items.Add(lvwItem)
Me.Groups(lvwGroup.Name).Items.Add(lvwItem)
Else
lvwItem = New ListViewItem
lvwItem.Text = dr.Item(0)
For i As Integer = 1 To NoColumns - 1
lvwItem.SubItems.Add(dr.Item(i))
Next
Me.Items.Add(lvwItem)
Me.Groups(lvwGroup.Name).Items.Add(lvwItem)
End If
Next
Else
For Each dr As DataRow In Data.Rows
lvwItem = New ListViewItem
lvwItem.Text = dr.Item(0)
For i As Integer = 1 To NoColumns - 1
lvwItem.SubItems.Add(dr.Item(i))
Next
Me.Items.Add(lvwItem)
Next
End If
AutoSizeColumns()
End Sub
End Class