VB.NET中LISTVIEW排序(原创-示例版)

VB.NET中ListView加载数据和排序功能的实现

        平时我们在VB.NET中开发数据库相关的程序都会用到DataGrid来显示数据,它的使用相对简单,也有排序的功能,基本能满一般的要求。但有时它并不能满足项目的功能需求,这时我们就想到了用ListView,虽然它的功能正是我们所要的,必竞它不是一个数据库的控件,不能像DataGrid那样通过简单的设置就可以显示数据,同时也没有排序的功能,这些就要我们自已用程序代码来实现了。前些天在开发一个项目时就写了一段使用ListView显示数据并实现排序的代码,简单地说一下它的实现原理:显示数据是通过循环读取数据记录,用ListView的Add方法将数据添加到ListView中;排序的功能是通过ListView列的点击事件来得到要排序的字段,再使用ORDER BY关键字组合SQL重新加载数据来实现排序的。欢迎使用VB.NTE的朋友一起交流,我的EMAIL是[email protected]
   
    以下是程序所使用的数据库及控件的设置信息:

数据库名:Northwind(SQL SERVER 2000中自带的,如果没有此数据库请先建立)
表    名:Products(如果没有这个表,请使用后面附带的SQL语句建立)

窗 体 名:frmListViewDb

所用控件

Label    1个
属性:Text=ProductName:

-----------------------------------------------------

TextBox  1个
属性:Name=txtProductName

-----------------------------------------------------

Button   5个
(1) 属性:Name=btnFilter、Text=过滤
(2) 属性:Name=btnShowAll、Text=全部
(3) 属性:Name=btnSelAll、Text=全选
(4) 属性:Name=btnCancelSelAll、Text=取消全选
(5) 属性:Name=btnInsteadSel、Text=反选
(5) 属性:Name=btnInfo、Text=查看

ListView   1个
属性:Name=ListViewDb、View=Details、Sorting=None、GridLines=True,FullRowSelect=True,CheckBoxs=True,Size=856,416、Columns添加10个列,Width=150,Text分别为:ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued

    源程序:
Imports System.Data.SqlClient
Public Class frmListViewDb
    Inherits System.Windows.Forms.Form

    '定义数据库连接对象
    Dim sdConn As New SqlConnection
    Dim conString As String = "data source=127.0.0.1;initial catalog=Northwind;uid=sa;password=123456"

    '定义记录db2ListView执行状态的变量
    Dim Dbr As Integer

    '定义记录默认排序方式的变量
    Dim mySort As String = "ASC"

    '定义记录默认排序字段的变量
    Dim myField As String = "ProductID"

    '定义记录上次排序的字段在LISTVIEW中的列ID的变量
    Dim pOrderID As Integer = 0

    '定义复选操作的相关变量
    Dim i As Integer
    Dim sCount As Integer

#Region " Windows 窗体设计器生成的代码 "

    Public Sub New()
        MyBase.New()

        '该调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        '在 InitializeComponent() 调用之后添加任何初始化

    End Sub

    '窗体重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Windows 窗体设计器所必需的
    Private components As System.ComponentModel.IContainer

    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改此过程。
    '不要使用代码编辑器修改它。
    Friend WithEvents txtProductName As System.Windows.Forms.TextBox
    Friend WithEvents btnFilter As System.Windows.Forms.Button
    Friend WithEvents btnShowAll As System.Windows.Forms.Button
    Friend WithEvents ListViewDb As System.Windows.Forms.ListView
    Friend WithEvents ColumnHeader1 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader2 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader3 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader4 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader5 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader6 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader7 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader8 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader9 As System.Windows.Forms.ColumnHeader
    Friend WithEvents ColumnHeader10 As System.Windows.Forms.ColumnHeader
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents btnSelAll As System.Windows.Forms.Button
    Friend WithEvents btnCancelSelAll As System.Windows.Forms.Button
    Friend WithEvents btnInsteadSel As System.Windows.Forms.Button
    Friend WithEvents btnInfo As System.Windows.Forms.Button
    Private Sub InitializeComponent()
        Me.ListViewDb = New System.Windows.Forms.ListView
        Me.ColumnHeader1 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader2 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader3 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader4 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader5 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader6 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader7 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader8 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader9 = New System.Windows.Forms.ColumnHeader
        Me.ColumnHeader10 = New System.Windows.Forms.ColumnHeader
        Me.txtProductName = New System.Windows.Forms.TextBox
        Me.btnFilter = New System.Windows.Forms.Button
        Me.btnShowAll = New System.Windows.Forms.Button
        Me.Label1 = New System.Windows.Forms.Label
        Me.btnSelAll = New System.Windows.Forms.Button
        Me.btnCancelSelAll = New System.Windows.Forms.Button
        Me.btnInsteadSel = New System.Windows.Forms.Button
        Me.btnInfo = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'ListViewDb
        '
        Me.ListViewDb.CheckBoxes = True
        Me.ListViewDb.Columns.AddRange(New System.Windows.Forms.ColumnHeader() {Me.ColumnHeader1, Me.ColumnHeader2, Me.ColumnHeader3, Me.ColumnHeader4, Me.ColumnHeader5, Me.ColumnHeader6, Me.ColumnHeader7, Me.ColumnHeader8, Me.ColumnHeader9, Me.ColumnHeader10})
        Me.ListViewDb.FullRowSelect = True
        Me.ListViewDb.GridLines = True
        Me.ListViewDb.Location = New System.Drawing.Point(8, 64)
        Me.ListViewDb.Name = "ListViewDb"
        Me.ListViewDb.Size = New System.Drawing.Size(856, 416)
        Me.ListViewDb.TabIndex = 0
        Me.ListViewDb.View = System.Windows.Forms.View.Details
        '
        'ColumnHeader1
        '
        Me.ColumnHeader1.Text = "ProductID"
        Me.ColumnHeader1.Width = 100
        '
        'ColumnHeader2
        '
        Me.ColumnHeader2.Text = "ProductName"
        Me.ColumnHeader2.Width = 150
        '
        'ColumnHeader3
        '
        Me.ColumnHeader3.Text = "SupplierID"
        Me.ColumnHeader3.Width = 150
        '
        'ColumnHeader4
        '
        Me.ColumnHeader4.Text = "CategoryID"
        Me.ColumnHeader4.Width = 150
        '
        'ColumnHeader5
        '
        Me.ColumnHeader5.Text = "QuantityPerUnit"
        Me.ColumnHeader5.Width = 150
        '
        'ColumnHeader6
        '
        Me.ColumnHeader6.Text = "UnitPrice"
        Me.ColumnHeader6.Width = 150
        '
        'ColumnHeader7
        '
        Me.ColumnHeader7.Text = "UnitsInStock"
        Me.ColumnHeader7.Width = 150
        '
        'ColumnHeader8
        '
        Me.ColumnHeader8.Text = "UnitsOnOrder"
        Me.ColumnHeader8.Width = 150
        '
        'ColumnHeader9
        '
        Me.ColumnHeader9.Text = "ReorderLevel"
        Me.ColumnHeader9.Width = 150
        '
        'ColumnHeader10
        '
        Me.ColumnHeader10.Text = "Discontinued"
        Me.ColumnHeader10.Width = 150
        '
        'txtProductName
        '
        Me.txtProductName.Font = New System.Drawing.Font("宋体", 12.0!)
        Me.txtProductName.Location = New System.Drawing.Point(88, 16)
        Me.txtProductName.Name = "txtProductName"
        Me.txtProductName.Size = New System.Drawing.Size(200, 26)
        Me.txtProductName.TabIndex = 1
        Me.txtProductName.Text = ""
        '
        'btnFilter
        '
        Me.btnFilter.Location = New System.Drawing.Point(296, 16)
        Me.btnFilter.Name = "btnFilter"
        Me.btnFilter.Size = New System.Drawing.Size(75, 26)
        Me.btnFilter.TabIndex = 2
        Me.btnFilter.Text = "过滤"
        '
        'btnShowAll
        '
        Me.btnShowAll.Location = New System.Drawing.Point(384, 16)
        Me.btnShowAll.Name = "btnShowAll"
        Me.btnShowAll.Size = New System.Drawing.Size(75, 26)
        Me.btnShowAll.TabIndex = 3
        Me.btnShowAll.Text = "全部"
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(8, 21)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(80, 16)
        Me.Label1.TabIndex = 4
        Me.Label1.Text = "ProductName:"
        '
        'btnSelAll
        '
        Me.btnSelAll.Location = New System.Drawing.Point(472, 16)
        Me.btnSelAll.Name = "btnSelAll"
        Me.btnSelAll.Size = New System.Drawing.Size(75, 26)
        Me.btnSelAll.TabIndex = 5
        Me.btnSelAll.Text = "全选"
        '
        'btnCancelSelAll
        '
        Me.btnCancelSelAll.Location = New System.Drawing.Point(560, 16)
        Me.btnCancelSelAll.Name = "btnCancelSelAll"
        Me.btnCancelSelAll.Size = New System.Drawing.Size(65, 26)
        Me.btnCancelSelAll.TabIndex = 6
        Me.btnCancelSelAll.Text = "取消全选"
        '
        'btnInsteadSel
        '
        Me.btnInsteadSel.Location = New System.Drawing.Point(640, 16)
        Me.btnInsteadSel.Name = "btnInsteadSel"
        Me.btnInsteadSel.Size = New System.Drawing.Size(75, 26)
        Me.btnInsteadSel.TabIndex = 7
        Me.btnInsteadSel.Text = "反选"
        '
        'btnInfo
        '
        Me.btnInfo.Location = New System.Drawing.Point(728, 16)
        Me.btnInfo.Name = "btnInfo"
        Me.btnInfo.Size = New System.Drawing.Size(75, 26)
        Me.btnInfo.TabIndex = 7
        Me.btnInfo.Text = "查看"
        '
        'frmListViewDb
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 14)
        Me.ClientSize = New System.Drawing.Size(872, 493)
        Me.Controls.Add(Me.btnInsteadSel)
        Me.Controls.Add(Me.btnCancelSelAll)
        Me.Controls.Add(Me.btnSelAll)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.btnShowAll)
        Me.Controls.Add(Me.btnFilter)
        Me.Controls.Add(Me.txtProductName)
        Me.Controls.Add(Me.ListViewDb)
        Me.Controls.Add(Me.btnInfo)
        Me.Name = "frmListViewDb"
        Me.Text = "ListView加载数据排序功能"
        Me.ResumeLayout(False)

    End Sub

#End Region

    '***************************************************************************
    '函数功能:将读取出来的数据写入LISTVIEW中
    '函数名称:sd_Db2Listview,调用格式:sd_Db2Listview("A"),sd_Db2Listview("")
    '参    数:FilerStr,要查询的产品名,为空时则查询所有的
    '返 回 值:1为正常,-1为有错误
    '编 写 者:SD
    '日    期:2005-9-23
    '转载请保留此信息
    '***************************************************************************
    Private Function sd_Db2Listview(ByVal FilerStr As String) As Integer
        Try
            Cursor.Current = Cursors.WaitCursor

            '清除LISTVIEW中已有的数据
            ListViewDb.Items.Clear()

            Dim varSQL As String

            '定义数据库操作对象
            Dim cmd As SqlCommand
            Dim rd As SqlDataReader

            '定义LISTVIEW中的项目,用于写入数据
            Dim lsv As ListViewItem

            '建立数据库连接
            sdConn = New SqlConnection(conString)
            sdConn.Open()

            '构造查询及排序的SQL语句
            If FilerStr.Length > 0 Then
                varSQL = "SELECT * FROM Products WHERE ProductName LIKE '" & FilerStr & "%' ORDER BY " & myField & " " & mySort & ";"
            Else
                varSQL = "SELECT * FROM Products ORDER BY " & myField & " " & mySort & ";"
            End If

            '读取数据
            cmd = New SqlCommand(varSQL, sdConn)
            rd = cmd.ExecuteReader

            '写入数据到LISTVIEW中
            While rd.Read
                lsv = New ListViewItem(rd("ProductID").ToString)

                lsv.SubItems.Add(rd("ProductName").ToString)
                lsv.SubItems.Add(rd("SupplierID").ToString)
                lsv.SubItems.Add(rd("CategoryID").ToString)
                lsv.SubItems.Add(rd("QuantityPerUnit").ToString)
                lsv.SubItems.Add(rd("UnitPrice").ToString)
                lsv.SubItems.Add(rd("UnitsInStock").ToString)
                lsv.SubItems.Add(rd("UnitsOnOrder").ToString)
                lsv.SubItems.Add(rd("ReorderLevel").ToString)
                lsv.SubItems.Add(rd("Discontinued").ToString)

                ListViewDb.Items.Add(lsv)
            End While

            sdConn.Close()

            Cursor.Current = Cursors.Default
            Return sd_Db2Listview = 1
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
            Return sd_Db2Listview = -1
        Finally
            If sdConn.State = ConnectionState.Open Then
                sdConn.Close()
            End If
        End Try
    End Function

    '启动时即显示所有数据
    Private Sub frmListViewDb_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dbr = sd_Db2Listview("")
    End Sub

    '过滤显示数据
    Private Sub btnFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFilter.Click
        Try
            Dim FilerStr As String = ""
            FilerStr = txtProductName.Text.Trim().Replace("'", "")
            dbr=sd_Db2Listview(FilerStr)
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        Finally
            If sdConn.State = ConnectionState.Open Then
                sdConn.Close()
            End If
        End Try
    End Sub

    '显示所有数据
    Private Sub btnShowAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowAll.Click
        sd_Db2Listview("")
    End Sub

    '处理排序
    Private Sub ListViewDb_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListViewDb.ColumnClick
        '根据点击的列ID,得到排序的字段名
        Select Case e.Column.ToString
            Case 0
                myField = "ProductID"
            Case 1
                myField = "ProductName"
            Case 2
                myField = "SupplierID"
            Case 3
                myField = "CategoryID"
            Case 4
                myField = "QuantityPerUnit"
            Case 5
                myField = "UnitPrice"
            Case 6
                myField = "UnitsInStock"
            Case 7
                myField = "UnitsOnOrder"
            Case 8
                myField = "ReorderLevel"
            Case 9
                myField = "Discontinued"
        End Select

        '清除上次排序列的标记
        ListViewDb.Columns(pOrderID).Text = ListViewDb.Columns(pOrderID).Text.Replace(" ▼", "").Replace(" ▲", "")

        '显示排序方式
        If mySort = "ASC" Then
            ListViewDb.Columns(e.Column.ToString).Text = ListViewDb.Columns(e.Column.ToString).Text & " ▼"
            mySort = "DESC"
        Else
            mySort = "ASC"
            ListViewDb.Columns(e.Column.ToString).Text = ListViewDb.Columns(e.Column.ToString).Text & " ▲"
        End If

        '重新加载数据
        sd_Db2Listview(txtProductName.Text.Trim())
        ListViewDb.Refresh()

        '记住上次排序的列ID,以便清除,否则将会出现排序过的列都有排序的标记
        pOrderID = e.Column.ToString
    End Sub

    '全选
    Private Sub btnSelAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelAll.Click
        sCount = ListViewDb.Items.Count - 1

        For i = 0 To sCount
            ListViewDb.Items(i).Checked = True
        Next i
    End Sub

    '取消全选
    Private Sub btnCancelSelAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancelSelAll.Click
        sCount = ListViewDb.Items.Count - 1

        For i = 0 To sCount
            ListViewDb.Items(i).Checked = False
        Next i
    End Sub

    '反选
    Private Sub btnInsteadSel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsteadSel.Click
        sCount = ListViewDb.Items.Count - 1

        For i = 0 To sCount
            If ListViewDb.Items(i).Checked Then
                ListViewDb.Items(i).Checked = False
            Else
                ListViewDb.Items(i).Checked = True
            End If
        Next i
    End Sub

    '得到复选框选择的ID
    Private Sub btnInfo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInfo.Click
        Dim SelLst As String = ""
        Dim unSelLst As String = ""

        sCount = ListViewDb.Items.Count - 1

        For i = 0 To sCount
            If ListViewDb.Items(i).Checked Then
                SelLst = SelLst & ListViewDb.Items(i).SubItems(0).Text.ToString() & ","
            Else
                unSelLst = unSelLst & ListViewDb.Items(i).SubItems(0).Text.ToString() & ","
            End If
        Next i

        If SelLst.Length > 0 Then
            MsgBox("复选框选中的记录ID有:" & SelLst, MsgBoxStyle.Information)
        End If

        If unSelLst.Length > 0 Then
            MsgBox("复选框未选中的记录ID有:" & unSelLst, MsgBoxStyle.Information)
        End If
    End Sub
End Class

    附:
    生成Products表的SQL语句:
CREATE TABLE [dbo].[Products] (
 [ProductID] [int] IDENTITY (1, 1) NOT NULL ,
 [ProductName] [nvarchar] (40) COLLATE Chinese_PRC_CI_AS NOT NULL ,
 [SupplierID] [int] NULL ,
 [CategoryID] [int] NULL ,
 [QuantityPerUnit] [nvarchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
 [UnitPrice] [money] NULL ,
 [UnitsInStock] [smallint] NULL ,
 [UnitsOnOrder] [smallint] NULL ,
 [ReorderLevel] [smallint] NULL ,
 [Discontinued] [bit] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Products] ADD
 CONSTRAINT [DF_Products_UnitPrice] DEFAULT (0) FOR [UnitPrice],
 CONSTRAINT [DF_Products_UnitsInStock] DEFAULT (0) FOR [UnitsInStock],
 CONSTRAINT [DF_Products_UnitsOnOrder] DEFAULT (0) FOR [UnitsOnOrder],
 CONSTRAINT [DF_Products_ReorderLevel] DEFAULT (0) FOR [ReorderLevel],
 CONSTRAINT [DF_Products_Discontinued] DEFAULT (0) FOR [Discontinued],
 CONSTRAINT [PK_Products] PRIMARY KEY  CLUSTERED
 (
  [ProductID]
 )  ON [PRIMARY] ,
 CONSTRAINT [CK_Products_UnitPrice] CHECK ([UnitPrice] >= 0),
 CONSTRAINT [CK_ReorderLevel] CHECK ([ReorderLevel] >= 0),
 CONSTRAINT [CK_UnitsInStock] CHECK ([UnitsInStock] >= 0),
 CONSTRAINT [CK_UnitsOnOrder] CHECK ([UnitsOnOrder] >= 0)
GO

ALTER TABLE [dbo].[Products] ADD
 CONSTRAINT [FK_Products_Categories] FOREIGN KEY
 (
  [CategoryID]
 ) REFERENCES [dbo].[Categories] (
  [CategoryID]
 ),
 CONSTRAINT [FK_Products_Suppliers] FOREIGN KEY
 (
  [SupplierID]
 ) REFERENCES [dbo].[Suppliers] (
  [SupplierID]
 )
GO

 

你可能感兴趣的:(VB.NET)