使用LargeIcon View无法使用OwnerDrawn Listview正确覆盖OnDrawItem

时间:2014-06-10 06:35:21

标签: vb.net listview ownerdrawn

我正在尝试使用LargeIcon视图完成我的自定义Listview控件。我想在OnDrawItem事件中自定义绘制Item。

到目前为止,我有以下代码:

Protected Overrides Sub OnDrawItem(e As DrawListViewItemEventArgs)
    Dim flags As TextFormatFlags
    Dim subColour As Color = Color.Black
    Dim subBackColour As Color = Color.Empty

    Try
        If Not (e.State And ListViewItemStates.Selected) = 0 Then
            'Draw the background for a selected item.
            e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Highlight, e.Bounds)
            e.DrawFocusRectangle()
        Else
            'Draw the background for an unselected item.
            e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Control, e.Bounds)
        End If

        e.DrawBackground()

        'Draw the Icons
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality
        e.Item.ImageList.Draw(e.Graphics, New Point(20, 22), 0)
        e.Graphics.ResetTransform()
        e.DrawFocusRectangle()

        'Draw the Text
        flags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.Bottom
        Dim rec As New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width + 10, e.Bounds.Height + 10)
        TextRenderer.DrawText(e.Graphics, e.Item.Text, Me.Font, rec, subColour, subBackColour, flags)

        MyBase.OnDrawItem(e)

    Catch ex As Exception
        ErrorTrap(ex, "ListView_Stores: OnDrawItem()")
    End Try
End Sub

然而,当我运行我的代码时,它正确地绘制了我的文本和图标,但我似乎无法按照下面的图片使项目突出显示正确:

enter image description here

它没有正确地突出显示任何颜色(只是一个虚线方块),它甚至没有突出显示对象的整个边界 - 它在文本的一半处剁碎。

想知道是否有人可以帮助或至少指出我正确的方向。 感谢

1 个答案:

答案 0 :(得分:1)

好的,通过 LOT 的研究和反复试验,我通过覆盖自定义类中的ListItem的OnDraw事件,成功实现了我的目标。我不确定它是否是正确的(或首选)方法,但我对结果感到满意。

我最终利用ColorMatrix方法覆盖了蓝色'突出显示我所选项目的颜色。然后,当未选中时,我只是将我的ColorMatrix设置为空

我的新修订代码:

Protected Overrides Sub OnDrawItem(e As DrawListViewItemEventArgs)
    Dim storeName_flags As New StringFormat
    Dim storeCode_flags As New StringFormat
    Dim matrixItems As Single()() = { _
           New Single() {0, 0, 0, 0, 0}, _
            New Single() {0, 0.6F, 0, 0, 0}, _
             New Single() {0, 0, 3, 0, 0}, _
              New Single() {0, 0, 0, 1, 0}, _
               New Single() {0, 0, 0, 0, 1}}
    Dim colorMatrix As ColorMatrix = New ColorMatrix(matrixItems)
    Dim imgattr As ImageAttributes = New ImageAttributes
    Dim bmp As Bitmap = New Bitmap(My.Resources.Store_Good)

    Try
        'Get StoreName and StoreNum from original e.Item.Text
        Dim StoreDetail As String() = e.Item.Text.Split(New Char() {"|"c})
        Dim StoreName As String = StoreDetail(0)
        Dim StoreNum As String = StoreDetail(1)

        'Declare Image Rectangle as the max size of the bitmap
        Dim Image_Width As Integer = bmp.Width
        Dim Image_Height As Integer = bmp.Height
        Dim imgRect As New Rectangle(e.Bounds.X + ((e.Bounds.Width - Image_Width) / 2), e.Bounds.Y, Image_Width, Image_Height)

        'Declare Text Rectangle 
        Dim textSize As SizeF = New SizeF(e.Graphics.MeasureString(StoreName, Me.Font, 100))
        Dim textRect As New Rectangle(e.Bounds.X + ((e.Bounds.Width - textSize.Width) / 2), e.Bounds.Bottom - textSize.Height, textSize.Width + 1, textSize.Height)

        e.Graphics.SmoothingMode = SmoothingMode.HighQuality

        If e.Item.Selected Then
            'Set the Image to use the 'blue' color matrix and highlight the text
            imgattr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)
            e.Graphics.FillRectangle(System.Drawing.SystemBrushes.Highlight, textRect)
        Else
            'Turn off the color matrix and draw the default background
            imgattr = Nothing
            e.DrawBackground()
        End If

        'Draw the Image
        e.Graphics.DrawImage(bmp, imgRect, 0, 0, Image_Width, Image_Height, GraphicsUnit.Pixel, imgattr)
        storeCode_flags.Alignment = StringAlignment.Center
        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
        Dim rect2 As New Rectangle(e.Bounds.X + ((e.Bounds.Width - Image_Width) / 2) + 1, e.Bounds.Y + 15, Image_Width, Image_Height)
        e.Graphics.DrawString(StoreNum, New Font(CustomFnt.Families(0), 24, FontStyle.Bold, GraphicsUnit.Pixel), Brushes.Black, rect2, storeCode_flags)

        'Draw the Text
        storeName_flags.Alignment = StringAlignment.Center
        storeName_flags.LineAlignment = StringAlignment.Far
        storeName_flags.FormatFlags = StringFormatFlags.FitBlackBox
        e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
        e.Graphics.DrawString(StoreName, Me.Font, Brushes.Black, textRect, storeName_flags)

        bmp.Dispose()
        MyBase.OnDrawItem(e)

    Catch ex As Exception
        ErrorTrap(ex, "ListView_Stores: OnDrawItem()")
    End Try
End Sub

现在而不是:

enter image description here

我明白了:

enter image description here