ListView Final Column Autosize creates scrollbar

前端 未结 8 884
闹比i
闹比i 2021-01-13 18:23

I am implementing a custom control which derives from ListView.

I would like for the final column to fill the remaining space (Quite a common task), I have gone abou

相关标签:
8条回答
  • 2021-01-13 19:11

    This may be pretty late, but i believe the easiest solution is to add a function to handle the window resize event. I have my listview anchored to the right, so when i resize my window, the listview also resizes. in the function that handles the window resize, i set the myListView.Columns[lastColumnIndex].Width = -2;

    This apparently redraws the listview, extending the last column to the edge of the control. Hope this helps.

    0 讨论(0)
  • 2021-01-13 19:12

    ObjectListView (an open source wrapper around .NET WinForms ListView) allows this "expand-last-column-to-fill-available-space". It's actually more difficult to get right than it first appears -- do not believe anyone who tells you otherwise :)

    If you use ObjectListView, you get the solution to that problem -- and several others -- for free. But if you want to do all the work yourself, you'll need to:

    • use ClientSize instead of DisplayRectangle (as @zxpro has already said)
    • use Layout event rather than Resize event.
    • listen for ColumnResized event and do the same work
    • not do the auto resizing in design mode -- it gets very confusing.

    The trickiest problem only appears when the window shrinks -- the horizontal scroll bar flickers annoyingly and sometimes remains after the shrinking is finished. Which appears to be exactly what is happening in your case.

    The solution is to intercept the WM_WINDOWPOSCHANGING message and resize the ListView to what the new size is going to be.

    protected override void WndProc(ref Message m) {
        switch (m.Msg) {
            case 0x46: // WM_WINDOWPOSCHANGING
                this.HandleWindowPosChanging(ref m);
                base.WndProc(ref m);
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }
    
    protected virtual void HandleWindowPosChanging(ref Message m) {
        const int SWP_NOSIZE = 1;
    
        NativeMethods.WINDOWPOS pos = (NativeMethods.WINDOWPOS)m.GetLParam(typeof(NativeMethods.WINDOWPOS));
        if ((pos.flags & SWP_NOSIZE) == 0) {
            if (pos.cx < this.Bounds.Width) // only when shrinking
                // pos.cx is the window width, not the client area width, so we have to subtract the border widths
                this.ResizeFreeSpaceFillingColumns(pos.cx - (this.Bounds.Width - this.ClientSize.Width));
        }
    }
    
    0 讨论(0)
提交回复
热议问题