Results 1 to 4 of 4

Thread: Custom ListView that is DataGrid like

  1. #1

    Thread Starter
    Fanatic Member MetalKid's Avatar
    Join Date
    Aug 2005
    Location
    Green Bay, Wisconsin
    Posts
    534

    Custom ListView that is DataGrid like

    This ListView has some extra features that a normal ListView doesn't have. First, you have add all the columns that you want to show. You provide the column name (from a datatable/dataview), the header text, the width (in pixels), and the cell alignment of the text (left, center, right). After that, you can LoadData, passing in a datatable or dataview, along with a start and ending index of the rows you want displayed (not providing any will default to show all rows). This will also automatically handle any and all sorting via a DataView. (If you sent in a datatable, I automatically put it into a dataview).

    VB Code:
    1. Imports System.ComponentModel
    2. Imports System.Drawing
    3.  
    4. Public Class MKPPListView
    5.    Inherits System.Windows.Forms.ListView
    6.  
    7. #Region "<< Variables >>"
    8.    Private _columns As ArrayList
    9.    Private _captions As ArrayList
    10.    Private _widths As ArrayList
    11.    Private _dataSource As Object
    12.    Private _start As Int32
    13.    Private _finish As Int32
    14.    Private _contextMenu As ContextMenu
    15.    Private _helpText As String
    16.    Private _sorting As Boolean
    17. #End Region
    18.  
    19. #Region "<< Properties >>"
    20.    <Browsable(True), DefaultValue(True)> _
    21.    Public Property AllowSorting() As Boolean
    22.       Get
    23.          Return _sorting
    24.       End Get
    25.       Set(ByVal Value As Boolean)
    26.          _sorting = Value
    27.       End Set
    28.    End Property
    29.    <Browsable(True)> _
    30.    Public Property HelpText() As String
    31.       Get
    32.          Return _helpText
    33.       End Get
    34.       Set(ByVal Value As String)
    35.          _helpText = Value
    36.       End Set
    37.    End Property
    38.    <Browsable(False)> _
    39.    Public ReadOnly Property SelectedIndex() As Int32
    40.       Get
    41.          For i As Int32 = 0 To Me.Items.Count - 1
    42.             Dim row As ListViewItem = Me.Items(i)
    43.             If row.Selected = True Then
    44.                Return i
    45.             End If
    46.          Next
    47.          Return -1
    48.       End Get
    49.    End Property
    50.    Public Property RowFilter() As String
    51.       Get
    52.          If TypeOf _dataSource Is DataView Then
    53.             Return CType(_dataSource, DataView).RowFilter
    54.          End If
    55.       End Get
    56.       Set(ByVal Value As String)
    57.          If TypeOf _dataSource Is DataView Then
    58.             CType(_dataSource, DataView).RowFilter = Value
    59.          End If
    60.       End Set
    61.    End Property
    62.    Public Property SortData() As String
    63.       Get
    64.          If TypeOf _dataSource Is DataView Then
    65.             Return CType(_dataSource, DataView).Sort
    66.          End If
    67.       End Get
    68.       Set(ByVal Value As String)
    69.          If TypeOf _dataSource Is DataView Then
    70.             CType(_dataSource, DataView).Sort = Value
    71.             MyBase.Items.Clear()
    72.             SetupListView()
    73.          End If
    74.       End Set
    75.    End Property
    76.    Public ReadOnly Property Count() As Int32
    77.       Get
    78.          Return MyBase.Items.Count
    79.       End Get
    80.    End Property
    81. #End Region
    82.  
    83. #Region "<< Startup >>"
    84.    Public Sub New()
    85.       MyBase.New()
    86.       _columns = New ArrayList
    87.       _widths = New ArrayList
    88.       _captions = New ArrayList
    89.       MyBase.View = View.Details
    90.       MyBase.FullRowSelect = True
    91.       MyBase.MultiSelect = False
    92.       MyBase.ForeColor = Color.Yellow
    93.       MyBase.BackColor = Color.Black
    94.       MyBase.AllowColumnReorder = True
    95.       MyBase.Scrollable = True
    96.       _sorting = True
    97.       AddColumn("", "", 0, HorizontalAlignment.Center)
    98.       _contextMenu = New ContextMenu
    99.       Me.ContextMenu = _contextMenu
    100.       Me.ContextMenu.MenuItems.Add(New MenuItem("What's This?", AddressOf WhatsThis))
    101.    End Sub
    102. #End Region
    103.  
    104. #Region "<< Helper Methods >>"
    105.    Private Sub WhatsThis(ByVal sender As Object, ByVal e As EventArgs)
    106.       Help.ShowPopup(Me, HelpText, System.Windows.Forms.Form.MousePosition)
    107.    End Sub
    108. #End Region
    109.  
    110. #Region "<< Public Methods >>"
    111.    Public Sub SetCaption(ByVal index As Int32, ByVal newCaption As String)
    112.       _captions(index) = newCaption
    113.       Me.Columns(index).Text = newCaption
    114.    End Sub
    115.    Public Function SelectedItem(ByVal Column As String) As String
    116.       Dim i As Int32
    117.       For i = 0 To _columns.Count - 1
    118.          If CType(_columns(i), String) = Column Then
    119.             Return SelectedItem(i)
    120.          End If
    121.       Next
    122.       Throw New DataException(Column & " does not exist!")
    123.    End Function
    124.    Public Function SelectedItem(ByVal Column As Int32) As String
    125.       Dim selected As New ListView.SelectedListViewItemCollection(Me)
    126.       If selected.Count = 0 Then
    127.          Return Nothing
    128.       Else
    129.          Return selected.Item(0).SubItems(Column).Text
    130.       End If
    131.    End Function
    132.    Public Function SelectedItem() As ListViewItem
    133.       Dim selected As New ListView.SelectedListViewItemCollection(Me)
    134.       If selected.Count = 0 Then
    135.          Return Nothing
    136.       Else
    137.          Return selected.Item(0)
    138.       End If
    139.    End Function
    140.    Public Sub TypeFind(ByVal item As String, ByVal Column As String)
    141.       Dim i As Int32
    142.       For i = 0 To _columns.Count - 1
    143.          If CType(_columns(i), String) = Column Then
    144.             TypeFind(item, i)
    145.             Exit For
    146.          End If
    147.       Next
    148.    End Sub
    149.    Public Sub TypeFind(ByVal item As String, ByVal Column As Int32)
    150.       Dim i As Int32
    151.       For i = 0 To MyBase.Items.Count - 1
    152.          If MyBase.Items(i).SubItems(Column).Text.ToLower.StartsWith(item.ToLower) Then
    153.             MyBase.Items(i).EnsureVisible()
    154.             MyBase.Items(i).Selected = True
    155.             Exit For
    156.          End If
    157.       Next
    158.    End Sub
    159.    Public Sub SetAlternateRowColor(ByVal ForeColor As Color, ByVal BackColor As Color)
    160.       Dim i As Int32
    161.       For i = 0 To MyBase.Items.Count - 1
    162.          If i Mod 2 = 1 Then
    163.             MyBase.Items(i).BackColor = BackColor
    164.             MyBase.Items(i).ForeColor = ForeColor
    165.          End If
    166.       Next
    167.    End Sub
    168. #End Region
    169.  
    170. #Region "<< Add Column >>"
    171.    Public Sub AddColumn(ByVal Column As String, ByVal Caption As String)
    172.       AddColumn(Column, Caption, 0)
    173.    End Sub
    174.    Public Sub AddColumn(ByVal Column As String, ByVal Caption As String, ByVal Width As Int32)
    175.       AddColumn(Column, Caption, Width, HorizontalAlignment.Left)
    176.    End Sub
    177.    Public Sub AddColumn(ByVal Column As String, ByVal Caption As String, ByVal Alignment As HorizontalAlignment)
    178.       AddColumn(Column, Caption, 0, Alignment)
    179.    End Sub
    180.    Public Sub AddColumn(ByVal Column As String, ByVal Caption As String, ByVal Width As Int32, ByVal Alignment As HorizontalAlignment)
    181.       _columns.Add(Column)
    182.       _captions.Add(Caption)
    183.       _widths.Add(Width)
    184.       MyBase.Columns.Add(Caption, Width, Alignment)
    185.    End Sub
    186. #End Region
    187.  
    188. #Region "<< Load Data >>"
    189.    Public Sub LoadData(ByRef Data As DataTable)
    190.       LoadData(Data, 0, Data.Rows.Count - 1)
    191.    End Sub
    192.    Public Sub LoadData(ByRef Data As DataView)
    193.       LoadData(Data, 0, Data.Count - 1)
    194.    End Sub
    195.    Public Sub LoadData(ByRef Data As DataTable, ByVal Start As Int32, ByVal Finish As Int32)
    196.       LoadData(New DataView(Data), Start, Finish)
    197.    End Sub
    198.    Public Sub LoadData(ByRef Data As DataView, ByVal Start As Int32, ByVal Finish As Int32)
    199.       MyBase.Items.Clear()
    200.       _dataSource = Data
    201.       _start = Start
    202.       _finish = Finish
    203.       SetupListView()
    204.    End Sub
    205. #End Region
    206.  
    207. #Region "<< SetupListView >>"
    208.    Private Sub SetupListView()
    209.       Dim i As Int32, j As Int32
    210.       If TypeOf _dataSource Is DataTable Then
    211.          With CType(_dataSource, DataTable)
    212.             For i = _start To _finish
    213.                Dim item As New ListViewItem(.Rows(i)(CType(_columns(1), Int32)).ToString)
    214.                For j = 1 To _columns.Count - 1
    215.                   item.SubItems.Add(.Rows(i)(CType(_columns(j), Int32)).ToString)
    216.                Next
    217.                MyBase.Items.Add(item)
    218.             Next
    219.          End With
    220.       ElseIf TypeOf _dataSource Is DataView Then
    221.          With CType(_dataSource, DataView)
    222.             For i = _start To _finish
    223.                Dim item As New ListViewItem(.Item(i)(CType(_columns(1), String)).ToString)
    224.                For j = 1 To _columns.Count - 1
    225.                   item.SubItems.Add(.Item(i)(CType(_columns(j), String)).ToString)
    226.                Next
    227.                MyBase.Items.Add(item)
    228.             Next
    229.          End With
    230.       End If
    231.       If MyBase.Columns(1).Width = 0 Then
    232.          Dim gr As Graphics = MyBase.CreateGraphics
    233.          For i = 1 To _columns.Count - 1
    234.             Dim width As Int32 = CType(gr.MeasureString(MyBase.Columns(i).Text, Me.Font).Width, Int32)
    235.             width += 5
    236.             For j = 0 To MyBase.Items.Count - 1
    237.                Dim myWidth As Int32 = CType(gr.MeasureString(MyBase.Items(j).SubItems(i).Text, MyBase.Font).Width, Int32)
    238.                If i > 1 Then
    239.                   myWidth += 5
    240.                End If
    241.                If myWidth > width Then
    242.                   width = myWidth
    243.                End If
    244.             Next
    245.             MyBase.Columns(i).Width = width
    246.             width = 0
    247.          Next
    248.       End If
    249.    End Sub
    250. #End Region
    251.  
    252. #Region "<< Column Sorting >>"
    253.    Private Sub MKPPListView_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles MyBase.ColumnClick
    254.       If AllowSorting Then
    255.          If TypeOf _dataSource Is DataView Then
    256.             Dim col As String = MyBase.Columns(e.Column).Text
    257.             Dim i As Int32
    258.             For i = 0 To _captions.Count - 1
    259.                If CType(_captions(i), String) = col Then
    260.                   col = CType(_columns(i), String)
    261.                   Exit For
    262.                End If
    263.             Next
    264.             If CType(_dataSource, DataView).Sort = col Then
    265.                CType(_dataSource, DataView).Sort = col & " DESC"
    266.             Else
    267.                CType(_dataSource, DataView).Sort = col
    268.             End If
    269.             MyBase.Items.Clear()
    270.             SetupListView()
    271.          End If
    272.       End If
    273.    End Sub
    274. #End Region
    275.  
    276. End Class

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Custom ListView that is DataGrid like

    It would be preferable to declare a DataSource property to maintain consistency with the existing .NET data-binding mechanism. Also, every DataTable already has an associated DataView in its DefaultView property.

  3. #3

    Thread Starter
    Fanatic Member MetalKid's Avatar
    Join Date
    Aug 2005
    Location
    Green Bay, Wisconsin
    Posts
    534

    Re: Custom ListView that is DataGrid like

    Thanks for the feedback.

  4. #4
    Member
    Join Date
    Feb 2005
    Location
    Chennai-India
    Posts
    38

    Re: Custom ListView that is DataGrid like

    It will be more comfortable, if it is posted as a solution file
    Programming is not a MAGIC

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width