Wine Too
Wine Too

Reputation: 4655

Resize form on listview height

I have form with only docked.full listview on it. Listview show computer drives so it's content is changeable on runtime. On listview column headers are allways visible.
I would like my form to resize with listview regarding of filled items.

This is my code:

Dim rc As Rectangle = lvDriveInfo.Items(0).GetBounds(ItemBoundsPortion.Entire)           
Me.Height = (rc.Height * lvDriveInfo.Items.Count) +
             SystemInformation.CaptionHeight +
             SystemInformation.BorderSize.Height

But something misses here or is incorrect.
How to get exact height of listview with headers regarding on items.count and properly set height of form with this value?

Upvotes: 0

Views: 3642

Answers (2)

Hans Passant
Hans Passant

Reputation: 941515

ListView metrics are rather convoluted, what you are trying to do is most definitely not easy. The one thing you overlooked is the space required by the column headers. That however is not enough, ListView also requires a bit of extra elbow room at the bottom to avoid displaying the scrollbar.

The most straight-forward code that works on my machine is:

Private Sub ResizeView()
    If ListView1.Items.Count = 0 Then Exit Sub
    Dim last = ListView1.Items(ListView1.Items.Count - 1)
    Me.ClientSize = New Size(Me.ClientSize.Width, _
                             ListView1.Top + last.Bounds.Bottom + 4)
End Sub

The +4 is the rub, I can't give you a warranty that this will work on every Windows version at every video DPI. It is independent of the item height so that's encouraging. But testing required to be sure. If you can guarantee that there will never be too many items in the list then you can avoid the problem by setting the list view's Scrollable property to False.

Upvotes: 4

David -
David -

Reputation: 2031

Try the following code

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    lvDriveInfo.BorderStyle = BorderStyle.None
    lvDriveInfo.Dock = DockStyle.Fill

    With lvDriveInfo
        .View = View.Details
        .GridLines = True
        .Columns.Add("Drive")
    End With

    SetFormHeight()
End Sub

Private Sub SetFormHeight()
    lvDriveInfo.Items.Clear()

    For Each Drive In IO.DriveInfo.GetDrives
        lvDriveInfo.Items.Add(Drive.Name)
    Next

    Dim ListViewHeaderHeight As Integer = lvDriveInfo.Items(0).Bounds.Top
    Dim ListViewRowHeight As Integer = lvDriveInfo.Items(0).Bounds.Height
    Dim ListViewRowsCount As Integer = lvDriveInfo.Items.Count
    Dim NewHeight As Integer = ListViewHeaderHeight + (ListViewRowHeight * ListViewRowsCount)

    Me.ClientSize = New Size(Me.ClientSize.Width, NewHeight)
End Sub

Upvotes: 1

Related Questions