代码之家  ›  专栏  ›  技术社区  ›  ryan

在ListView中居中显示子项图标

  •  1
  • ryan  · 技术社区  · 17 年前

    我想在我的一列中居中显示图标。我当前添加图标的方式是在创建行后调用AddicOnSubItem方法。如何修改自定义控件以使图标居中?

    谢谢

    Public Class ListViewSubIcons : Inherits System.Windows.Forms.ListView
    
        Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Int32, ByVal wParam As Int32, ByRef lParam As LV_ITEM) As Boolean
    
        Public Structure LV_ITEM
            Public mask As UInt32
            Public iItem As Int32
            Public iSubItem As Int32
            Public state As UInt32
            Public stateMask As UInt32
            Public pszText As String
            Public cchTextMax As Int32
            Public iImage As Int32
            Public lParam As IntPtr
        End Structure
    
        Private Structure NMHDR
            Public hwndFrom As IntPtr
            Public idFrom As Integer
            Public code As Integer
        End Structure
    
        ' listview
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Private Structure LVHITTESTINFO
            Public pt As Point
            Public flags As Integer
            Public iItem As Integer
            Public iSubItem As Integer
        End Structure
    
        Public Const LVM_FIRST As Int32 = &H1000
        Public Const LVM_GETITEM As Int32 = LVM_FIRST + 5
        Public Const LVM_SETITEM As Int32 = LVM_FIRST + 6
        Public Const LVIF_TEXT As Int32 = &H1
        Public Const LVIF_IMAGE As Int32 = &H2
    
        Public Const LVW_FIRST As Integer = &H1000
        Public Const LVM_GETEXTENDEDLISTVIEWSTYLE As Integer = LVW_FIRST + 54
    
        Public Const LVS_EX_GRIDLINES As Integer = &H1
        Public Const LVS_EX_SUBITEMIMAGES As Integer = &H2
        Public Const LVS_EX_CHECKBOXES As Integer = &H4
        Public Const LVS_EX_TRACKSELECT As Integer = &H8
        Public Const LVS_EX_FULLROWSELECT As Integer = &H20 ' applies to report mode only
    
        Private Const WM_NOTIFY As Integer = &H4E
    
        ' Change the style to accept images on subitems.
        Public Sub New()
    
            ' This call is required by the Windows.Forms Form Designer.
            InitializeComponent()
    
            AddHandler Me.HandleCreated, AddressOf ListViewWithIcons_HandleCreated
    
        End Sub
    
        Private Sub ListViewWithIcons_HandleCreated(ByVal sender As Object, ByVal e As EventArgs)
            ' Change the style of listview to accept image on subitems
            Dim m As System.Windows.Forms.Message = New Message
            m.HWnd = Me.Handle
            m.Msg = LVM_GETEXTENDEDLISTVIEWSTYLE
            m.LParam = New IntPtr(LVS_EX_GRIDLINES Or LVS_EX_FULLROWSELECT Or LVS_EX_SUBITEMIMAGES Or LVS_EX_CHECKBOXES Or LVS_EX_TRACKSELECT)
            m.WParam = IntPtr.Zero
            Me.WndProc(m)
        End Sub
    
        ' Add an icon to a subitem.
        Public Sub AddIconToSubitem(ByVal row As Integer, ByVal col As Integer, ByVal icon_num As Integer)
            Dim lvi As New LV_ITEM()
            lvi.iItem = row
            lvi.iSubItem = col
    
            ' Indicate what we're setting.
            lvi.mask = LVIF_IMAGE
            lvi.iImage = icon_num   ' Image index in the ImageList.
    
            ' Send the LVM_SETITEM message.
            SendMessage(Me.Handle, LVM_SETITEM, 0, lvi)
        End Sub
    
    End Class
    
    1 回复  |  直到 17 年前
        1
  •  1
  •   ryan    17 年前

    我将在这里回答我自己的问题:)

    Public Class ListViewSubIcons : Inherits System.Windows.Forms.ListView
    
        Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
        Public Const LVW_FIRST As Integer = &H1000
        Public Const LVM_GETEXTENDEDLISTVIEWSTYLE As Integer = LVW_FIRST + 54
    
        Public Const LVS_EX_GRIDLINES As Integer = &H1
        Public Const LVS_EX_SUBITEMIMAGES As Integer = &H2
        Public Const LVS_EX_CHECKBOXES As Integer = &H4
        Public Const LVS_EX_TRACKSELECT As Integer = &H8
        Public Const LVS_EX_FULLROWSELECT As Integer = &H20 ' applies to report mode only
    
        Private Const WM_NOTIFY As Integer = &H4E
    
        Public Enum ListStatus
            OK
            Fail
            Upgrade
        End Enum
    
        Private _liststatus As ListStatus = ListStatus.OK
        Public WriteOnly Property SetListStatus() As ListStatus
            Set(ByVal value As ListStatus)
                _liststatus = value
            End Set
        End Property
    
    
        ' Change the style to accept images on subitems.
        Public Sub New()
    
            ' This call is required by the Windows.Forms Form Designer.
            InitializeComponent()
    
            AddHandler Me.HandleCreated, AddressOf ListViewWithIcons_HandleCreated
            AddHandler Me.DrawSubItem, AddressOf lvResult_DrawSubItem
            AddHandler Me.DrawColumnHeader, AddressOf lvResult_DrawColumnHeader
    
            Me.OwnerDraw = True
    
        End Sub
    
        Private Sub ListViewWithIcons_HandleCreated(ByVal sender As Object, ByVal e As EventArgs)
            ' Change the style of listview to accept image on subitems
            Dim m As System.Windows.Forms.Message = New Message
            m.HWnd = Me.Handle
            m.Msg = LVM_GETEXTENDEDLISTVIEWSTYLE
            m.LParam = New IntPtr(LVS_EX_GRIDLINES Or LVS_EX_FULLROWSELECT Or LVS_EX_SUBITEMIMAGES Or LVS_EX_CHECKBOXES Or LVS_EX_TRACKSELECT)
            m.WParam = IntPtr.Zero
            Me.WndProc(m)
        End Sub
    
        ' Handle DrawSubItem event
        Private Sub lvResult_DrawSubItem(ByVal sender As Object, ByVal e As         DrawListViewSubItemEventArgs)
    
            'Only subitems with just icon's will have no text
            If e.SubItem.Text = "" Then
                Dim xpos = e.SubItem.Bounds.Location.X + (e.SubItem.Bounds.Width / 2) - 8
                Dim p As New PointF(xpos, e.SubItem.Bounds.Location.Y)
                e.DrawBackground()
                Select Case _liststatus
                    Case ListStatus.OK
                        e.Graphics.DrawImage(My.Resources.Symbol_Check, p)
                    Case ListStatus.Fail
                        e.Graphics.DrawImage(My.Resources.Delete, p)
                    Case ListStatus.Upgrade
                        e.Graphics.DrawImage(My.Resources.Component1, p)
                End Select
            Else
                e.DrawDefault = True
            End If
    
        End Sub
    
        ' Handle DrawColumnHeader event
        Private Sub lvResult_DrawColumnHeader(ByVal sender As Object, ByVal e As DrawListViewColumnHeaderEventArgs)
            e.DrawDefault = True
            e.DrawBackground()
            e.DrawText()
        End Sub
    
    End Class