You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.Net中创建OwnerDraw ListView的实现求助

VB ListView OwnerDraw 实现左侧图片+右侧三标签布局(入门指南+代码示例)

入门指引

  • 启用OwnerDraw:将ListView的OwnerDraw属性设为True,这是接管控件绘制逻辑的核心开关
  • 核心事件:重点处理DrawItem事件,每个列表条目绘制时都会触发该事件,所有自定义绘制逻辑都写在这里
  • 绘图基础:依赖Windows GDI函数(如DrawText、SetBkColor)实现精确布局,这些函数是VB OwnerDraw的核心工具
  • 数据管理:用ListView条目的Tag属性绑定自定义数据(如图片索引、文本内容),避免硬编码,方便后续维护

完整代码示例

假设你已经在窗体上添加了:

  • ListView控件(命名lvCustom)
  • ImageList控件(命名imgList,提前添加好需要的图片)
Option Explicit

' 自定义类型存储每个条目的完整数据
Private Type ListItemData
    imgIndex As Integer ' 对应ImageList中的图片索引
    mainText As String  ' 主标题
    subText As String   ' 副标题
    descText As String  ' 描述文本
End Type

Private Sub Form_Load()
    ' 初始化ListView基础设置
    With lvCustom
        .OwnerDraw = True
        .View = lvwList
        .FullRowSelect = True
        .Font.Name = "微软雅黑"
        .Font.Size = 9
        .Width = 400
        .Height = 300
    End With
    
    ' 添加测试条目(可根据需求循环添加)
    Dim testData As ListItemData
    Dim newItem As ListItem
    
    testData.imgIndex = 1
    testData.mainText = "项目名称"
    testData.subText = "分类:工具"
    testData.descText = "更新时间:2024-05-20"
    
    Set newItem = lvCustom.ListItems.Add(, , "") ' 文本留空,自定义绘制
    newItem.Tag = testData
End Sub

Private Sub lvCustom_DrawItem(ByVal Index As Integer, ByVal rc As Rect, ByVal State As Integer)
    Dim itemData As ListItemData
    Dim hdc As Long
    Dim imgArea As Rect
    Dim textArea As Rect
    
    ' 获取当前条目的绑定数据(注意ListView索引从1开始,DrawItem的Index从0开始)
    itemData = lvCustom.ListItems(Index + 1).Tag
    hdc = lvCustom.hdc
    
    ' 绘制背景(区分选中/正常状态)
    If (State And lvwSelected) Then
        SetBkColor hdc, RGB(45, 137, 239)
        SetTextColor hdc, vbWhite
    Else
        SetBkColor hdc, vbWhite
        SetTextColor hdc, vbBlack
    End If
    ExtTextOut hdc, 0, 0, ETO_OPAQUE, rc, vbNullString, 0, vbNullString
    
    ' 绘制左侧图片(居中对齐)
    With imgArea
        .Left = rc.Left + 8
        .Top = rc.Top + (rc.Bottom - rc.Top - imgList.ListImages(itemData.imgIndex).Height) / 2
        .Right = .Left + imgList.ListImages(itemData.imgIndex).Width
        .Bottom = .Top + imgList.ListImages(itemData.imgIndex).Height
    End With
    imgList.ListImages(itemData.imgIndex).Draw hdc, imgArea.Left, imgArea.Top, imlNormal
    
    ' 绘制右侧三行文本
    textArea.Left = imgArea.Right + 12
    textArea.Right = rc.Right - 8
    
    ' 第一行:主标题(加粗)
    textArea.Top = rc.Top + 6
    textArea.Bottom = textArea.Top + 18
    lvCustom.Font.Bold = True
    SetTextColor hdc, IIf((State And lvwSelected), vbWhite, RGB(26, 26, 26))
    DrawText hdc, itemData.mainText, Len(itemData.mainText), textArea, DT_LEFT Or DT_VCENTER
    
    ' 第二行:副标题(常规)
    textArea.Top = textArea.Bottom + 3
    textArea.Bottom = textArea.Top + 16
    lvCustom.Font.Bold = False
    SetTextColor hdc, IIf((State And lvwSelected), vbLightGray, RGB(68, 68, 68))
    DrawText hdc, itemData.subText, Len(itemData.subText), textArea, DT_LEFT Or DT_VCENTER
    
    ' 第三行:描述文本(小字号)
    textArea.Top = textArea.Bottom + 3
    textArea.Bottom = textArea.Top + 14
    lvCustom.Font.Size = 8
    SetTextColor hdc, IIf((State And lvwSelected), vbLightGray, RGB(102, 102, 102))
    DrawText hdc, itemData.descText, Len(itemData.descText), textArea, DT_LEFT Or DT_VCENTER
    
    ' 恢复默认字号
    lvCustom.Font.Size = 9
End Sub

关键技巧

  • 坐标计算:用Rect结构体定位元素,通过计算实现图片垂直居中、文本行间距均匀,避免布局错乱
  • 状态适配:必须处理选中、焦点等状态的颜色切换,保证交互体验一致
  • 性能优化:复用设备上下文(hdc),减少重复的字体、颜色设置操作
  • 数据解耦:通过Tag绑定数据,绘制逻辑和数据存储分离,方便后续修改条目内容或扩展字段
  • 视觉层级:通过字体粗细、大小、颜色区分文本优先级,提升可读性

内容的提问来源于stack exchange,提问作者steinernils

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:38:21