VB ListView的使用

参考网站: http://blog.sina.com.cn/s/blog_61090e890100gipa.html

ListView控件比前面几种控件要复杂一些,通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本。ListView控件是由ColumnHeader和ListItem对象所组成的,其中ColumnHeader对象的个数决定了控件的列数,而ListItem对象的个数则决定了控件的行数。(图7)
  ColumnHeader对象是ListView控件中包含标头文字的项目。利用ColumnHeader对象,用户可以:
  ▲单击对象触发ColumnClick事件并根据数据项目将项目排序。
  ▲拖动对象的右边框来调整列宽度。
  ▲在报表视图中隐藏ColumnHeader对象。
  ColumnHeader对象的数目决定每个ListItem对象可包含的子项目数目。删除ColumnHeader对象后所有与列关联的子项目也将被删除,并且每个ListItem对象的子项目数组将平移以更新ColumnHeader的索引,而这将导致剩余的列标头SubItemIndex属性的改变。

ColumnHeader对象的SubItemIndex属性
  该属性返回与ListView控件中ColumnHeader对象关联的子项目的索引。子项目是字符串数组,代表显示在报表视图中的ListItem对象的数据。第一列的列标头SubItemIndex属性设置为0,这是因为小图标和ListItem对象的文字总出现在第一列中,而且它们被当作ListItem对象而不是子项目。列标头数目取决于子项目数目。列标头数目总是比子项目数目多1。
  在设计时可以利用属性页的“列首”选项卡将ColumnHeader对象添加到ListView控件中,在运行时则用Add方法添加

ColumnHeader对象的Add方法
  该方法的使用与前面那些控件基本相似,就不再介绍了。
  ListView1.ColumnHeader.Add(index,key,text,width,alignment)
  ListItem对象是指控件中的一行(不包含标头行)的所有内容。它也可包含文本和图片,但是要使用图片则必须通过Icons和SmallIcons属性引用ImageList控件。

ListItem对象的SubItems属性
  返回或设置一个字符串(子项目)数组,它代表ListView控件中ListItem对象的数据。
  ListItem对象可包含任意多个的关联项目数据字符串(子项目),但每个ListItem对象子项目数目必须相同。每个子项目都对应于相关的列标头,无法直接向子项目数组添加元素,只有通过ColumnHeaders的Add方法添加列标头的方法添加子项目。

ListItem对象的Add方法 
  该方法添加ListItem对象到ListView控件的ListItems集合中并返回对新创建对象的引用。
它的语法如下:

  ListItem1.Add(index,icon,smallIcon)

ListView控件的View属性
  ListView控件可使用四种不同视图显示项目,这可以用View属性来确定。该属性返回或设置ListView控件中ListItem对象的外观。
  ListView控件的SortOrder,SortKey和Sorted属性
  控件中的ListItem对象可以按要求进行排序,与排序有关的属性是SortOrder,Sorted和SortKey属性
SortOrder属性返回或设置一个值,此值决定ListView控件中的ListItem对象以升序或降序排序。
  SortKey属性返回或设置一个值,此值决定ListView控件中的ListItem对象如何排序。
  Sorted属性返回或设置确定ListView控件中的ListItem对象是否排序的值。
  下面的代码说明了如何创建ColumnHeaders和ListItem对象,SubItemIndex和SubItem属性的使用方法以及如何排序。

Private Sub Form_load()
 '确保ListView控件的view属性为报表视图。
  ListView1.View=lvwReport
 '添加三列。
  ListView1.ColumnHeaders.Add,"Name","姓名"
  ListView1.ColumnHeaders.Add,"Sex","性别"
  ListView1.ColumnHeaders.Add,"Age","年龄"
  '向控件添加ListItem对象。
  Dim itmX As ListItem
  '添加column1的名称
  Set itmX=ListView1.ListItems.Add(1,"ZL","张力")
  '使用SubItemIndex将SubItem与正确的ColumnHeader关联。使用关键字("Sex")指定正确的ColumnHeader。
  itmX.SubItems(ListView1.ColumnHeaders("Sex").SubItemIndex)="男"
  '使用ColumnHeader关键字将SubItems字符串与
'正确的ColumnHeader关联。
  itmX.SubItems(ListView1.ColumnHeaders("Age").SubItemIndex)="19"
  Set itmX=ListView1.ListItems.Add(1,"LF","李芳")
  itmX.SubItems(ListView1.ColumnHeaders("Sex").SubItemIndex)="男"
  itmX.SubItems(ListView1.ColumnHeaders("Age").SubItemIndex)="22"
  Set itmX=ListView1.ListItems.Add(1,"WW","王伟")
  itmX.SubItems(ListView1.ColumnHeaders("Sex").SubItemIndex)="男"
  itmX.SubItems(ListView1.ColumnHeaders("Age").SubItemIndex)="24"
 End Sub

Private Sub ListView1_ColumnClick(ByVal ColumnHeader AsComctlLib.ColumnHeader)
  Select Case ColumnHeader.Key
   Case "Sex":ListView1.SortKey=1
    ListView1.SortOrder=lvwAscending
    ListView1.Sorted=True
   Case "Age":ListView1.SortKey=2
    ListView1.SortOrder=lvwAscending
    ListView1.Sorted=True
  End Select
 End Sub

一、ListView使用简介
  ListView控件是VB开发者非常喜爱的控件之一。作为Windows95公共控件组(COMCTL32.OCX)的成员,它经常与经常与TreeView、ImageList等控件联合使用。即用TreeView显示一个的树型结构,而用ListView显示选中的节点(Node)对 象的记录集。
  这是笔者在开发财务软件项目中的<<凭证管理>>模块的一个用户界面。屏幕左边是一个TreeView控件,用来显示会计凭证的类别;右边是一个ListView,用来显示对应类别的凭证目录;上方是一个菜单条控件(MenuBar)和一个工具条控件(ToolBar);下方是一个状态栏控件(StatusBar),用来显示凭证数个当前日期。

  大家可以看到图中所示的界面非常类似于Window95/98的资源浏览器,Windows的界面风格做为一种标准已为广大用户所接受。而Windows操作系统的主要的优点就是为所有的应用程序提供了公用的界面。知道如何使用基于Windows的应用程序的用户,很容易学会使用其他应用程序。

  这种使用Windows95公共控件组合的方法能够达到与Windows界面的一致性,所以在目前VB5.0应用程序的开发中经常使用。

二、填充大量结果集所遇到的问题
  在实际应用开发中,经常用ListView填充一个数据库 结果集(Recordset)的内容。即先写一段SQL查询语句,产生一个结果集,然后将结果集的每一条记录用DO...LOOP循环语句中填到ListView中。
  但是当结果集很大时(例如有5000条以上的记录) ,填充所需要的时间会很长。用户不得不等很长时间完成一个查询。所以在查询的过程中必须允许用户按Escape键退出。具体做法是在DO...LOOP循环体中加一条DoEvents函数,并写一段中断退出程序代码

  DoEvents函数功能是:转让控制权,以便让操作系统处理其它的事件。这样在长时间的查询过程中,如果用户按了Escape键,将退出循环 体,结束查询过程。

  但是这样又会引发另外一个问题:由于DoEvents可以让操作系统响应别的事件,循环体中填充每一条ListView项目(ListItem)的过程也会显示出来,所以在填充的过程中屏幕会不停的闪动,这种现象当然不能被用户所接受。如何 解决这个问题呢?

三、解决方
  用WindowsAPI函数可以解决这个问题。首先对几个 用到的API函数做一解释和说明。
  1.GetClientRect Lib "user32" (ByVal hwnd As Long,lpRect As RECT)As Long

  此函数功能是获得一个指定对象窗口(Window) 的矩型框区域(rectangle)。

  Hwnd为指定对象或窗体的句柄。LpRect为返回矩 型框的结构(必须定义为结构类型的变量)。

  2.ValidateRect Lib "user32" (ByVal hwnd As Long,lpRect AsRECT) As Long

  此函数功能是使指定的矩型区域生效。这样会 通知Windows不必对指定的区域进行重画(Redraw)。

  3.InvalidateRect Lib "user32" (ByVal hwnd As Long,lpRect AsRECT,ByVal bErase As Long) As Long

  此函数功能是使指定的矩型区域无效。这样会 通知Windows要对指定的区域进行重画。

  具体实现的步骤如下:

  1.在填充结果集之前先用GetClientRect函数获 得ListView的显示区域。

  2.在增加完一个显示项目(ListItem)后用ValidateRect函数置这一区域为有效。这样Windows就不会显示每一条ListItem,屏幕闪动的现象就会消 失。

  3.在填充结果集之后,用InvalidateRect函数置这一区域为无效。这样Windows就会重画ListView的内容,结果集被完整的显示出来。

  下面是笔者在项目开发中的一个程序实例。程序名为FillListView。该程序将填写一个Access数据库(FISCAL.MDB)的凭证表(Table)的内容到ListView中。

  首先进入VB5.0,新建一个窗体(Form),名为Form1。

  然后在Form中增加下列控件。


控 件 名 Name

ListView Lvw

Imagelist imlList

Command Button。 Command1


  将ImageList控件中充填一个名为“item”的图象后 与ListView控件关联。

  在<<工程>>菜单命令条中进入“引用”对话框,选择“MicrosoftDAOObjectLibrary”

  在Form的通用模块(Modle)中定义以下变量。

Private Type RECT ' 用 来 定 义 一 个 区 域 的 坐 标。

Left As Long

Top As Long

Right As Long

Bottom As Long

End Type

'   - -

' Windows API 函 数 的 声 明。

Private Declare Function InvalidateRect Lib "user32"

(ByVal hwnd As Long,lpRect As RECT,ByVal bErase As Long) AsLong

Private Declare Function ValidateRect Lib "user32"

(ByVal hwnd As Long,lpRect As RECT) As Long

Private Declare Function GetClientRect Lib "user32"

(ByVal hwnd As Long,lpRect As RECT) As Long


Dim mbSearchCancel As Boolean

' 用 来 定 义 查 询 中 断 的 标 志。

' True 表 示 中 止 查 询;False 表 示 正 在 查 询。


   将 该Form 的KeyPreview 属 性 设 为True, 以 控 制 窗 体 接 收 键 盘 事 件。

   然 后 在Form 的KeyPress 事 件 中 写 下 列 代 码:


If KeyAscii = vbKeyEscape Then

mbSearchCancel = True

' 当 用 户 按Escape 键 时, 置mbSearchCancel 变 量 为True。

End If

' 表 示 结 束 查 询。

在Command Button 的 Click 事 件 中 调 用 填 充 子 程 序:CallFillListView。


子 程 序 的 代 码 为:

Private Sub FillListView()

'

Dim itmX As ListItem ' 定 义 一 个ListView 的 显 示 项 目。

Dim ssql As String ' 查 询 字 串 变 量 。

'

Dim rc As RECT ' ListView 的 显 示 区 域。

Dim wrkJet As Workspace ' 数 据 库 工 作 空 间。

Dim dbFISCAL As Database ' 数 据 库 对 象。

Dim RS As Recordset ' 数 据 结 果 集。


On Error GoTo ErrFillListView


Screen.MousePointer = vbHourglass

lvw.ListItems.Clear: ' 清 除ListView 的 内 容。

'     

' 定 义ListView 的 列 头 的 名 称。

With lvw.ColumnHeaders

.Add," 凭 证 编 号",800

.Add," 凭 证 日 期",1000

.Add," 凭 证 字 号"," 凭 证 类 别"," 首 行 摘 要",1440

.Add," 借 方 金 额 合 计",1000,lvwColumnRight

End With


'   - - -

' 产 生 查 询 语 句。

ssql = "selectvoucher_id,voucher_number,voucher_date,voucher_type_shortname,"

ssql=ssql&"voucher_type_name,voucher_memo,voucher_amountfrom VOUCHER"

ssql = ssql & "order by voucher_number"

' '   - - -

' 打 开 一 个 数 据 库 结 果 集。

Set wrkJet = CreateWorkspace("NewJetWorkspace","admin","",dbUseJet)

Set dbFISCAL = wrkJet.OpenDatabase("FISCAL.mdb")

Set RS=. dbFISCAL .Open ssql,dbOpenForwardOnly

'     

' 获 得listview 的 显 示 区 域。

Call GetClientRect(lvw.hwnd,rc)


Do While Not RS.EOF()

DoEvents

If mbSearchCancel Then

' 中 断 退 出

RS.Close: Set RS = Nothing ' 关 闭、 清 除 结 果 集。

mbSearchCancel = False

Screen.MousePointer = vbDefault

'   - -

' 刷 新ListView 的 内 容, 显 示 已 经 查 出 的 记 录 数。

Call InvalidateRect(lvw.hwnd,rc,True)

Exit Sub

End If

'   - - -

' 增 加 一 个 显 示 项 目ListItem。

With lvw.ListItems

Set itmX = .Add(,"" & RS!voucher_number,"item","item")

' 凭 证 编 号

itmX.SubItems(1) = Format$("" & RS!voucher_date,"yyyy/mm/dd")

' 凭 证 日 期

itmX.SubItems(2) = "" &RS!voucher_type_shortname & "-" —

' 凭 证 字 号

& "" & RS!voucher_number


itmX.SubItems(3)="" & RS!voucher_type_name

' 凭 证 类 别

itmX.SubItems(4)=""&RS!voucher_memo

' 首 行 摘 要

itmX.SubItems(5)= Format$("" &RS!voucher_amount,"#,###.00")

' 借 方 合 计 金 额

itmX.Tag = "" & RS!voucher_id

End With

'   - -

' 避 免 显 示 区 域 的 闪 动 现 象。

Call ValidateRect(lvw.hwnd,rc)

RS.MoveNext

Loop


'  

'- 刷 新ListView 的 内 容。 显 示 所 有 查 出 的 记 录 数。

Call InvalidateRect(lvw.hwnd,True)

'   -

' 关 闭、 清 除 结 果 集。

RS.Close: Set RS = Nothing

creen.MousePointer = vbDefault

Exit Sub

ErrFillListView:

Screen.MousePointer = vbDefault

MsgBox Err & ":" & Error,vbInformation,Me.Caption

Exit Sub

End Sub


   编 写 完 毕 后 按F5 执 行 该 程 序, 用 鼠 标 点 击CommandButton, 将 开 始 查 询 并 填 写凭 证 的 内 容 到ListView 中 去。

   关 于ListView 本 文 只 是 描 述 了 它 如 何 填 充 大 量 结 果 集 的 方 法, 它 还 有 很多 特 性(property) 和 方 法(method), 利 用 它 们 可 以 达 到 更 完 美 的 显 示 效 果, 有 兴趣 的 读 者 可 以 进 一 步 研 究。 不 管 是 开 发 什 么 样 的 应 用 程 序, 只 有 坚 持 面 向 用 户、方 便 用 户 的 原 则, 这 样 的 软 件 才 具 有 强 大 的 生 命 力。

相关文章

Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 --------------------------...
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和...
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接...
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没...
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, t...
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integ...