Autosize. No, not the control, the text.

Originally posted to SOAPitStop, Nov 16, 2008.

It’s nice that .NET controls have an auto-size property so you don’t have to worry about overflow and all.  But what about cases where you have a fixed layout?  Well, that’s simple, you turn autosize off and fix the control to the size you need.

That’s half the story.  What about the text that’s inside it?  Now you know I’m talking to marketing people when I say that there are times you want the text to be as big as possible within that control.  But you can’t just set the font to a huge size, because sometimes you’ll have more text to display and the font size must regrettably be reduced.

To accommodate this, I made a quick method that brute-forces the correct font size in the control.  basically, stepping down the size of the font until it fits.  I know loops like this are cheap, poor programming, and I did give consideration to doing some hard math to calculate the proper font size based on the initial size, but sometimes not getting hung up on performance can be liberating.

    Private Sub ResizeText(ByVal c As Control)
        Dim currentSize As Size
        Dim currentFont As Font

        currentFont = c.Font

        Do
            currentSize = TextRenderer.MeasureText(c.Text, currentFont, _
                c.Size, TextFormatFlags.WordBreak)

            If currentSize.Width > (c.Width - c.Margin.Horizontal) _
                OrElse currentSize.Height > (c.Height - c.Margin.Vertical) Then

                currentFont = New Font(currentFont.FontFamily, _
                    CSng(currentFont.Size - 0.5), currentFont.Style, currentFont.Unit)
            Else
                Exit Do

            End If

        Loop While currentFont.Size >= 1

        c.Font = currentFont

    End Sub

/span

Columns Autosize: Listview in List View

Here’s another little snip of code I couldn’t find online when I needed it.  Geez, when I became a programmer, I wasn’t thinking I’d have to actually figure things out on my own.  That’s a lot of work.

Anyway, the problem I faced was when I had a Listview control on a form and I changed views from anything to List view, the columns of the items were really small, so I’d get ellipses’ after all the entries.  Sure, I could just set the column with to some obnoxious amount like 500, but that’s a waste of space.  So after searching and seeing a bunch of postings about using a Win32 API call to autoresize the column, then getting disappointed because it was for VB 4/5/6, I just hacked through it.

The Details view has an autosize feature, but apparently they didn’t extend it to the List view.  But we can still make use of it.  Why not switch to detail, set the autosize of column 0 to true, then measure how wide it makes the column, then use that as the column width in List view?  That’s a dumb idea.  Who would do something like that.  Oh, what do you know, it works.

Dim maxSize As Integer

lstItems.View = View.Details
lstItems.Columns(0).AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)
maxSize = lstItems.Columns(0).Width

lstItems.View = View.List
lstItems.Columns(0).Width = maxSize
lstItems.Refresh()

Yay.