使用ObjectListView自定义渲染器时的像素化文本

时间:2014-11-21 07:22:43

标签: vb.net graphics renderer objectlistview

我在网上找到了一个如何使用ObjectListView创建名片列表视图项的示例。它演示了如何使用自定义渲染器手动绘制控件中的每个Tile。

该示例涉及创建缓冲图形并手动绘制每个项目。我有这个工作,但是,我发现我在瓷砖上绘制的所有文字都看起来像素化(无论我使用什么设置),特别是如果我画小文本。例如,在普通表单上使用默认系统字体看起来很好,但在我的渲染器中它看起来是jagered。

代码如下所示:

Imports BrightIdeasSoftware
Imports System.Drawing.Drawing2D
Imports System.IO

Public Class StoreListRenderer
    Inherits AbstractRenderer
    Public Overrides Function RenderItem(e As DrawListViewItemEventArgs, g As Graphics, itemBounds As Rectangle, rowObject As Object) As Boolean
        ' If we're in any other view than Tile, return false to say that we haven't done
        ' the rendereing and the default process should do it's stuff
        Dim olv As ObjectListView = TryCast(e.Item.ListView, ObjectListView)
        If olv Is Nothing OrElse olv.View <> View.Tile Then
            Return False
        End If

        ' Use buffered graphics to kill flickers
        Dim buffered As BufferedGraphics = BufferedGraphicsManager.Current.Allocate(g, itemBounds)
        g = buffered.Graphics
        g.Clear(olv.BackColor)
        g.SmoothingMode = ObjectListView.SmoothingMode
        g.TextRenderingHint = ObjectListView.TextRenderingHint

        If e.Item.Selected Then
            Me.BorderPen = Pens.White
            Me.HeaderBackBrush = New SolidBrush(olv.HighlightBackgroundColorOrDefault)
        Else
            Me.BorderPen = New Pen(Color.FromArgb(&H33, &H33, &H33))
            Me.HeaderBackBrush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
        End If

        DrawStoreCard(g, itemBounds, rowObject, olv, DirectCast(e.Item, OLVListItem))

        ' Finally render the buffered graphics
        buffered.Render()
        buffered.Dispose()

        ' Return true to say that we've handled the drawing
        Return True
    End Function

    Friend BorderPen As New Pen(Color.FromArgb(&H33, &H33, &H33))
    Friend TextBrush As Brush = New SolidBrush(Color.FromArgb(&H22, &H22, &H22))
    Friend HeaderTextBrush As Brush = Brushes.AliceBlue
    Friend HeaderBackBrush As Brush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
    Friend BackBrush As Brush = Brushes.LemonChiffon
    Friend BackgroundBrush As Brush = New SolidBrush(Color.FromArgb(38, 38, 38))

    Public Sub DrawStoreCard(g As Graphics, itemBounds As Rectangle, rowObject As Object, olv As ObjectListView, item As OLVListItem)
        Try
            Dim _store As StoreObject = TryCast(rowObject, StoreObject)

            ' Allow a border around the card
            itemBounds.Inflate(-5, -5)
            g.FillRectangle(BackgroundBrush, itemBounds)

            Dim ColouredPanelRect As Rectangle = New Rectangle(itemBounds.Left + 7, itemBounds.Top + 7, 70, 70)
            g.FillRectangle(Brushes.IndianRed, ColouredPanelRect)

            Dim fmt As New StringFormat()
            fmt.Alignment = StringAlignment.Center
            fmt.LineAlignment = StringAlignment.Center

            For i As Integer = 0 To olv.Columns.Count - 1
                Dim column As OLVColumn = olv.GetColumn(i)
                If column.IsTileViewColumn Then

                    'Draw Store Number
                    Using font As New Font(fontMgr("Mentone Lig"), 36, FontStyle.Regular, GraphicsUnit.Pixel)
                        g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
                        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                        g.DrawString(_store.StoreID, font, BackgroundBrush, ColouredPanelRect, fmt)
                    End Using

                    'Draw Store Name
                    Using string_format As New StringFormat()
                        string_format.Alignment = StringAlignment.Center
                        string_format.LineAlignment = StringAlignment.Near
                        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                        g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
                        g.DrawString(_store.StoreName.ToUpper, New Font("Segoe UI", 9, FontStyle.Regular), Brushes.White, itemBounds, string_format)
                    End Using

...

我尝试过玩AntiAlias和ClearType,但两者都有相同的效果。

更新

以下是我在相同尺寸下使用相同字体的结果:

enter image description here

顶部的文字代表放置在表单上的普通标签。底部的文本是使用上面的代码绘制到listview项目(在平铺模式下)的文本。您可以轻松识别差异并发现它不是那么平滑。同样,我越大,文字越不平滑。我尝试过玩弄所有设置,目前设置为:

g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality

由于

1 个答案:

答案 0 :(得分:0)

好的,我最后再通过这个例子来解决这个问题。 问题是我从我的代码中删除了缩放元素,这似乎导致了文本的像素化。

通过添加以下代码,它已经纠正了文本的平滑度:

Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit

所以我的整体代码如下:

Using font As New Font("Segoe UI", 9, FontStyle.Regular)
     ' Measure the height of the title
     txt = column.GetStringValue(rowObject)
     Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
     g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
     g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
     g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
     g.PixelOffsetMode = PixelOffsetMode.HighQuality
     g.DrawString(txt, font, Brushes.LightGray, itemBounds, fmt)
End Using