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 about this via overriding the OnResize method:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (Columns.Count == 0)
return;
Columns[Columns.Count - 1].Width = -2; // -2 = Fill remaining space
}
or via another method:
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (!_autoFillLastColumn)
return;
if (Columns.Count == 0)
return;
int TotalWidth = 0;
int i = 0;
for (; i < Columns.Count - 1; i++)
{
TotalWidth += Columns[i].Width;
}
Columns[i].Width = this.DisplayRectangle.Width - TotalWidth;
}
Edit:
This works fine until I dock the ListView into a parent container and resize via that control. Every second time the control size shrinks (IE, drag the the border one pixel), I get a scroll bar on the bottom which can't move at all (not even one pixel).
The result of which is when I drag the size of the parent I am left with a flickering scroll bar in the ListView, and a 50% chance it will be there when the dragging stops.
You need to override the protected method
SetBoundsCore()
and perform the column resizing either before or after delegating tobase.SetBoundsCore()
, depending on whether the ListView width is narrowing or widening.The following example is hardcoded for a single column ListView:
Note his code doesn't deal with the
specified
parameter, i'll leave that up to you!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.
I know this is old question, but after reading this and then finding my own answer, I thought I would share for others reading this as well.
The fix for me (so far holding up under basic testing) was to set Docked to None and just Anchor my ListView to the top-left of the parent. Then, in the OnClientSize changed of the parent I set the size of my ListView to fill it, and then set my column width. For whatever reason, probably timing, this fixed the scrollbar issue mentioned by the original question.
CaseFilter is my ListView and ContentSplit.Panel1 is a SplitContainer control it is inside. When I had it set to Dock=Fill, I had the scrollbar issue, with the above changes, no problems.
Try calling
base.OnResize()
after you made your change.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:
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.
This code works very well for me:
Regards Lary