【问题标题】:Setting listbox item (by index) font bold设置列表框项目(按索引)字体粗体
【发布时间】:2016-04-28 08:48:26
【问题描述】:

我正在尝试将listbox 中的所有当前可用项目设置为粗体字。并且当稍后添加项目时,它们将具有默认字体。因此用户可以直观地看到最初列出的项目和新的项目。

从表单构造函数中,我像这样填充我的列表框,这些是添加的初始值。

Private Sub FillLinkedBox(ByVal oReferenceList As String())

    ' Fill the linked listbox with the current linked items
    Debug.Print(oReferenceList.ToString)
    lbLinkedParameters.Items.AddRange(oReferenceList)

    ' Set the font of all the existing items in the listbox
    For i As Integer = 0 To lbLinkedParameters.Items.Count - 1

       ' Set the font to bold for these items.

    Next

End Sub

用户完成后,我还想在处理时测试项目字体,以便我可以确定什么是初始值,什么不是(但我也可以将列表保存在内存中并检查项目是否列出)如果字体检查不是一个好的选择。

如果发现这个post 描述了应该执行此操作的东西,但它基于一个事件;我不明白它是如何工作的。

Dim buttonPressed As Boolean
Private Sub ListBox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem
e.DrawBackground()

    If ListBox1.SelectedIndices.Contains(e.Index) And buttonPressed Then
        e.Graphics.DrawString(ListBox1.Items(e.Index), e.Font, Brushes.Green, e.Bounds.X, e.Bounds.Y)

    Else
        e.Graphics.DrawString(ListBox1.Items(e.Index), e.Font, Brushes.Black, e.Bounds.X, e.Bounds.Y)
    End If
    If e.Index = ListBox1.Items.Count - 1 Then
        buttonPressed = False
    End If
    e.DrawFocusRectangle()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    buttonPressed = True
    ListBox1.Refresh()
End Sub

我的问题是:如何更改给定索引处列表框项的字体?

【问题讨论】:

  • 尝试使用 Datagridview。格式化行和单元格更容易
  • 是的,但是可以通过ListBox 以相对较低的难度完成。

标签: vb.net fonts listbox listboxitems


【解决方案1】:

it's based on an event; and I don't understand how it works.

如果将 ListControl (List/Combo) 设置为 OwnerDraw,则每次 Windows 需要绘制项目时都会触发 DrawItem 事件;您可以提供代码来更改颜色、字体或做其他事情。

After the user is finished I would also like to test the items font when processing

问题在于字体是基于项目的状态。正如您所描述的,这就是该项目是原始的还是添加的。该状态不能从索引中确定,您以后也不能从视觉元素(例如 绘制 的方式)重新确定该状态(您也不应该)。

所以手头的任务实际上是两个相关的事情:

  1. 向用户显示哪些项目是新的/添加的
  2. 以某种方式跟踪它们,以便代码可以确定它们

这将使用一个您可以添加到任何类的接口。这使得解决方案不那么针对这一本地化案例。

Public Interface IListItem
    Property Selected As Boolean
    Function GetDisplayText() As String  ' not really needed
End Interface

代码将使用Selected 来跟踪和绘制添加的项目。如果您愿意,可以更改名称,但您还必须更改绘制代码。

Public Class SimpleThing
    Implements IListItem

    ' your stuff
    Public Property Name As String
    Public Property Value As Int32
    Public Property Foo As Int32
    Public Property Bar As Single     

    Public Property Selected As Boolean Implements IListItem.Selected

    Public Sub New(n As String, v As Int32, 
                Optional b As Boolean = True)
        Name = n
        Value = v
        Selected = b
    End Sub

    Public Function GetDisplayText() As String Implements IListItem.GetDisplayText
        Return Name
    End Function

    Public Overrides Function ToString() As String
        Return Name
    End Function
End Class

GetDisplayText 是允许当项目显示在 ListControl 中时与其他情况不同的文本输出。这不是一个硬性要求。

SimpleThing 可以存储您需要的有关这些东西的任何信息,ListBox/ComboBox 绘图仅依赖于 IListItem 元素。您可以使用 List 作为DataSource 来填充控件:

ListThings = New List(Of SimpleThing)
...
ListThings.Add(New SimpleThing("Able", 42, True))
ListThings.Add(New SimpleThing("Baker", 7, True))
...
ListThings.Add(New SimpleThing("Ziggy", 6, True))

lbEnabler.DataSource = ListThings
lbEnabler.DisplayMember = "Name"
lbEnabler.ValueMember = "Value"

UI 控件设置为OwnerDrawFixed 并使用此代码绘制项目:

Private Sub lst_DrawItem(sender As Object, 
                    e As DrawItemEventArgs) Handles lbEnabler.DrawItem
    Dim lb As ListBox = CType(sender, ListBox)
    If e.Index < 0 Then
        TextRenderer.DrawText(e.Graphics, "", lb.Font, e.Bounds, lb.ForeColor)
        Return
    End If

    Dim bg As Color = If(e.State.HasFlag(DrawItemState.Selected),
                         SystemColors.Highlight, SystemColors.Window)
    Dim fg As Color = If(e.State.HasFlag(DrawItemState.Selected),
                         SystemColors.HighlightText, SystemColors.WindowText)

    Dim iItem As IListItem
    If TypeOf lb.Items(e.Index) Is IListItem Then
        iItem = CType(lb.Items(e.Index), IListItem)
    Else
        TextRenderer.DrawText(e.Graphics, lb.Items(e.Index).ToString, lb.Font, e.Bounds,
                              fg, bg, TextFormatFlags.Left Or
                              TextFormatFlags.VerticalCenter)
        Return
    End If
    e.DrawBackground()

    If iItem.Selected Then            ' change to IsOrginal or IsBold
        Using f As New Font(lb.Font.FontFamily, lb.Font.Size, FontStyle.Bold)
            TextRenderer.DrawText(e.Graphics, iItem.GetDisplayText(), f, e.Bounds,
                                  fg, bg, TextFormatFlags.Left Or
                                  TextFormatFlags.VerticalCenter)
        End Using
    Else
        '  default
        TextRenderer.DrawText(e.Graphics, iItem.GetDisplayText(), lb.Font, e.Bounds,
                              fg, bg, TextFormatFlags.Left Or
                              TextFormatFlags.VerticalCenter)
    End If

End Sub

结果:

就个人而言,我不认为这是一个很好的演示文稿。它是非标准的,Bold 所代表的含义并不是很明显。但是,您可以在 DrawItem 事件中做任何您想做的事情,例如添加图形指示器:

绿色加号版本非常清楚添加了哪些。获取添加了哪些项目也只需轮询项目集合:

Dim added = myListBox.Items.
                Cast(Of SimpleThing).
                Where(Function(f) f.Selected).
                ToArray()

【讨论】:

  • 如果这回答了问题,请单击复选标记,以便将其从未回答列表中移出。
猜你喜欢
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2016-08-10
  • 2015-09-23
  • 2015-03-11
  • 1970-01-01
相关资源
最近更新 更多