我在网上找到了一个如何使用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,但两者都有相同的效果。
更新
以下是我在相同尺寸下使用相同字体的结果:
顶部的文字代表放置在表单上的普通标签。底部的文本是使用上面的代码绘制到listview项目(在平铺模式下)的文本。您可以轻松识别差异并发现它不是那么平滑。同样,我越大,文字越不平滑。我尝试过玩弄所有设置,目前设置为:
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality
由于
答案 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