Nicolas78
Nicolas78

Reputation: 5144

Superfluous scroll bars in WinForms

I have a WinForms application with a ListView which scales with the main program window. OnResize, I adjust the width of the columns to fit the full width of the ListView. Now when I switch from fullscreen to normal, I get a horizontal scrollbar. This scrollbar cannot be scrolled, i.e. the width it covers is 100% of the width of the ListView. In other words, I want to get rid of this scrollbar. If I shortly touch the window resize handlers, without actually resizing the window, the width is recomputed and the scrollbar disappears. How can I get rid of that scrollbar automatically?

column1.Width = fixedWidth;
column2.Width = listView.Width - fixedWidth - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;

Upvotes: 1

Views: 725

Answers (2)

King King
King King

Reputation: 63317

To fill the remaining space with the last column's width you can do this, of course we have to do this whenever the form is resized:

//Resize event handler for your Form1
private void Form1_Resize(object sender, EventArgs e){
    column2.Width = -2;
}
//ColumnWidthChanged event handler
private void listView1_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e){
    int lastIndex = listView1.Columns.Count - 1;
    if (e.ColumnIndex != lastIndex) listView1.Columns[lastIndex].Width = -2;
}
//ColumnWidthChanging event handler
private void listView1_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e){
    int lastIndex = listView1.Columns.Count - 1;
    if (e.ColumnIndex != lastIndex) listView1.Columns[lastIndex].Width = -2;
}

NOTE: You said you had your ListView scaled with the main program window, I don't know what you did to achieve that, but I suggest you should use the Anchor property, set listView1.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;.

Upvotes: 2

Hans Passant
Hans Passant

Reputation: 941407

There are two problems. It starts with you using the listview's Width property. Which isn't correct on a ListView with borders, you need to use the ClientSize.Width property. The second problem is related to way automatic layout is calculated, it causes the Resize event to fire too soon. You can work around that by delaying the adjustment with Control.BeginInvoke(). Like this:

    private void listView1_Resize(object sender, EventArgs e) {
        this.BeginInvoke(new Action(() => {
            var lv = (ListView)sender;
            var w = 0;
            for (int ix = 0; ix < lv.Columns.Count - 1; ++ix) w += lv.Columns[ix].Width;
            w = Math.Max(0, lv.ClientSize.Width - w);
            lv.Columns[lv.Columns.Count - 1].Width = w;
        }));
    }

Upvotes: 3

Related Questions