Listbox Column Widths

I am trying to set my column widths in a Listbox to size according to the content in them. I am using the following with some success but all the columns are out of alignment until i click on the listbox and then they fall into alignment as per the code below. Am i doing this the wrong way? it looks almost right.

[code]Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean
if row > 0 and row < lvwTableData.ListCount - 1 then

if g.StringWidth(me.Cell(row,column)) > me.Column(column).WidthActual then
  me.Column(column).WidthExpression = str(g.StringWidth(me.Cell(row,column))+12)
end if

end if
End Function
[/code]

Maybe follow by ListboxName.Invalidate?

I think the issue may be trying to do it in the paint event…

Why not so it when adding the text to the listbox? You can Subclass and override Listbox.AddRow and Listbox.Cell(row,column) to do it then.

[quote=77378:@Karen Atkocius]I think the issue may be trying to do it in the paint event…

Why not so it when adding the text to the listbox? You can Subclass and override Listbox.AddRow and Listbox.Cell(row,column) to do it then.[/quote]

Hi Karen, Could you elaborate on this please.

Untested but subclass the Listbox and add methods:

[code]Sub AddRow(items() As String)
Super.AddRow items

Dim Row as Integer = me.LastIndex

For column as Integer = me.ColumnCount - DownTo 0

if g.StringWidth(me.Cell(row,column)) + 12 > me.Column(column).WidthActual then
  me.Column(column).WidthExpression = str(g.StringWidth(me.Cell(row,column))+12)
end if

Next
End Sub
[/code]

Sub AddRow(ParamArray item As String) me.AddRow item End Sub

[code]Sub InsertRow(row As Integer, text As String, indent As Integer = 0)
if g.StringWidth(text) + 12> me.Column(column).WidthActual then
me.Column(column).WidthExpression = str(g.StringWidth(text)+12)
end if

Super.InsertRow row, indent
End Sub
[/code]

[code]Sub Cell(row As Integer, column As Integer, Assigns Value As String)
if g.StringWidth( Value) + 12 > me.Column(column).WidthActual then
me.Column(column).WidthExpression = str(g.StringWidth(Value)+12)
end if

Super.Cell(row,column) = Value
End Sub
[/code]

If the listbox is hierarchical do the same for AddFolder and InsertFolder

Thank you very much. Most helpful

One problem is doing it that way may be slow if you are adding a lot of rows at one time.

You may want to have boolean which turns that off and resize columns separately when adding a lot of data and use the above only when making changes.

For the case of adding lot of rows at once, I would just track the maximum string width for each column when you are adding row, and only resize the columns after you have added all the rows in that batch.

BTW You need to use a picture (1X1 is OK) to get a graphics object for the above code… make it a property on the listbox and only create it on the first call. I forgot to include that.

[quote=77416:@Karen Atkocius]One problem is doing it that way may be slow if you are adding a lot of rows at one time.

You may want to have boolean which turns that off and resize columns separately when adding a lot of data and use the above only when making changes.

For the case of adding lot of rows at once, I would just track the maximum string width for each column when you are adding row, and only resize the columns after you have added all the rows in that batch.

BTW You need to use a picture (1X1 is OK) to get a graphics object for the above code… make it a property on the listbox and only create it on the first call. I forgot to include that.[/quote]
Yes I noticed this. I am just going to have it in my preferences that columns auto resize to fit contents