此链接上@Plutonix的参考答案 3D array loop and get the first dimension value
我正在修改的课程在组合框上显示TTF图像
Public Class FontItem
Public Property TTImageFile As Image
Public Property TTFile As String
Public Property TTBoldFile As String
Public Property Name As String
Public Sub New(i as Image, f As String, b As String, n As String)
TTImageFile = i
TTFile = f
TTBoldFile = b
Name = n
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Class
以这种方式使用此代码
Dim myFonts As New List(Of FontItem)
Dim data = {{My.Resources.arial, "Arial", "arial.ttf", "arialbd.ttf"},
{My.Resources.courier, "Courier New", "cour.ttf", "courbd.ttf"},
{My.Resources.verdana, "Verdana", "verdana.ttf", "verdanab.ttf"}}
For n As Int32 = 0 To data.GetUpperBound(0)
myFonts.Add(New FontItem(data(n, 0), data(n, 1), data(n, 2), data(n, 3)))
Next
AvialableFontsCombobox.DataSource = myFonts.ToArray()
其中“My.Resources.arial”和其他人是字体预览的png文件
代码工作正常但我的AvialableFontsCombobox只显示“arial.png”,“courier.png”...作为字符串而不是图形文件。
并添加
With AvialableFontsCombobox
.DrawMode = DrawMode.OwnerDrawVariable
End With
我只得到空格。
我缺少什么?我是否需要做更多的事情?
Private Sub AvialableFontsCombobox _DrawItem(sender As Object, e As DrawItemEventArgs) Handles AvialableFontsCombobox .DrawItem
答案 0 :(得分:1)
当您将Combo-
或ListBox
设置为OwnerDraw
时,您说您将处理项目的绘制 - 这意味着将代码添加到DrawItem
事件中。在这种情况下,您似乎想要为每个绘制一些PNG图像。另一种方法是在该Font中绘制每种字体(或示例文本)的名称。图像方法可能更容易,因为您可以确定每个图像的大小完全相同,即使这意味着在某些图像上有更多的空白区域。
首先是一些设置事项:
转动Option Strict On
。您正在存储来自资源的图像以及一个数组中的一些字符串,这意味着该数组为Object
。我喜欢将所有小块存放在一起的想法,但还有另一个问题......
您希望确保对My.Resources.fontname
的引用仅运行一次。每次运行代码时,都会创建一个新图像对象。如果你没有检查和处理旧的应用程序,你的应用程序将泄漏(上一个问题的列表更长)。
' form/class level declaration
Private FontImgs As Image()
在其他地方进行初始化:
' build it only once
If FontImgs Is Nothing Then
FontImgs = New Image() {My.Resources.Arial, My.Resources.Calibri,
My.Resources.Segoe, My.Resources.Verdana}
End If
Dim myFonts As New List(Of FontItem)
Dim data = {{"Arial", "arial.ttf", "arialbd.ttf"},
{"Calibri", "Calibri.ttf", "Calibri.ttf"},
{"Segoe", "Segoe.ttf", "Segoe.ttf"},
{"Verdana", "verdana.ttf", "verdanab.ttf"}
}
For n As Int32 = 0 To FontImgs.Length - 1
myFonts.Add(New FontItem(FontImgs(n), data(n, 1), data(n, 2), data(n, 0)))
Next
cboFonts.DataSource = myFonts
cboFonts.DisplayMember = "Name"
如果将列表初始化为彼此接近的列表,则可以很容易地确保图像引用的顺序与其余字体数据的顺序相同。顺便说一下,你的代码将Name作为FontFile传递 - 构造函数的顺序似乎不正确。
DataSource
如果这是在重新访问的Dialog表单上,请确保处理该数组中的图像,或者将其作为传递给表单的应用程序级别对象。
对于CBO:
设置完成后,在DrawItem
事件中添加一些代码:
Private Sub cboFonts_DrawItem(sender As Object,
e As DrawItemEventArgs) Handles cboFonts.DrawItem
' no item, early exit
If e.Index < 0 Then Return
e.DrawBackground()
' get the image from the cbo.fiontitem.imageprop
Dim img = DirectCast(cboFonts.Items(e.Index), FontItem).TTImageFile
' size of the image
Dim rect = New Rectangle(e.Bounds.X, e.Bounds.Y,
img.Width, img.Height)
' draw it
e.Graphics.DrawImage(img, rect)
e.DrawFocusRectangle()
End Sub
我认为我为图像使用了太大的字体,但你明白了。使用小于实际大小的rect
(缩略图)可以缩小图像,但实际上使用较小的字体/图像可能无法缩放。