I wonder how I might go about centering the heading of a ListBox column and yet have the contents of that same column aligned right. I cannot find if it is possible to distinguish between the column header and the contents.
Web or desktop?
Set the ListBox without Header.
Place a Canvas (a serie of Canvas) above the ListBox and draw the header by yourself (in the Canvas).
this is the common answer usually sent to these questions
Align the column itself with ColumnAlign and then align each cell with CellAlign as they are added.
Subclass listbox and add these properties:
Private mColumnAlignment() As Integer
Private mHeaderAlignment() As Integer
Private mHeaderAlignmentAll As Integer
Then add methods to access them:
[code]Sub ColumnAlignment(index As Integer, Assigns value As Integer)
ReDim mColumnAlignment(ColumnCount - 1)
mColumnAlignment(index) = value
Invalidate()
End Sub
Function ColumnAlignment(index As Integer) As Integer
ReDim mColumnAlignment(ColumnCount - 1)
Return mColumnAlignment(index)
End Function
Sub HeaderAlignment(index As Integer, Assigns value As Integer)
ReDim mHeaderAlignment(ColumnCount - 1)
ReDim mColumnAlignment(ColumnCount - 1)
If index = -1 Then
mHeaderAlignmentAll = value
For i As Integer = 0 To ColumnCount - 1
Super.ColumnAlignment(i) = value
Next
Else
Super.ColumnAlignment(index) = value
mHeaderAlignment(index) = value
End
Invalidate()
End Sub
Function HeaderAlignment(index As Integer) As Integer
ReDim mHeaderAlignment(ColumnCount - 1)
If index = -1 Then
Return mHeaderAlignmentAll
Else
Return mHeaderAlignment(index)
End
End Function[/code]
This is the CellTextPaint event handling:
Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean
Dim text As String = Cell(row, column)
Select Case mColumnAlignment(column)
Case Listbox.AlignLeft
x = 0
Case Listbox.AlignCenter
Dim blankWidth As Integer = g.Width - g.StringWidth(text)
If (blankWidth / 2) < 2 Then
x = 0
Else
x = blankWidth / 2 - 2
End
Case Listbox.AlignRight
Dim blankWidth As Integer = g.Width - g.StringWidth(text)
If (blankWidth / 2) < 2 Then
x = 0
Else
x = blankWidth - 4
End
Else
// TODO: Listbox.AlignDefault and Listbox.AlignDecimal
End
g.DrawString(text, x, y, g.Width - 4, True)
Return True
End Function
Use it like this:
[code]Sub Open()
Me.HasHeading = True
Me.ColumnsResizable = True
Me.ColumnCount = 4
Me.ColumnAlignment(0) = Listbox.AlignLeft
Me.ColumnAlignment(1) = Listbox.AlignCenter
Me.ColumnAlignment(2) = Listbox.AlignRight
Me.HeaderAlignment(-1) = Listbox.AlignCenter
// or set each header alignment separately
// Me.HeaderAlignment(0) = Listbox.AlignLeft
// Me.HeaderAlignment(1) = Listbox.AlignCenter
// Me.HeaderAlignment(2) = Listbox.AlignRight
Me.Heading(0) = “AlignLeft”
Me.Heading(1) = “AlignCenter”
Me.Heading(2) = “AlignRight”
Me.AddRow(“ABC”, “ABC”, “ABC”)
Me.AddRow(“x”, “x”, “x”)
Me.AddRow(“123456”, “123456”, “123456”)
End Sub
[/code]
Notes:
- Listbox.AlignDefault and Listbox.AlignDecimal are not handled in the CellTextPaint event
- CellAlignment is not handled in the CellTextPaint.
Thanks for the replies. I will try out the different solutions. I particularly like Eli’s, as it gives me some more experience with OOP (I think?).