Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / WPF
Tip/Trick

Simulate WPF ListView Column Width Set to "*"

Rate me:
Please Sign up or sign in to vote.
4.83/5 (9 votes)
29 May 2010CPOL2 min read 48.5K   3   2
One technique for having a column width that grows/shrinks with ListView width
I'm writing a WPF front-end to a new version of my CPAM library, and the application features a number of ListView controls. One of the things that the standard ListView DOES NOT do through simple property settings is all the programmer to set a column width of "*" (meaning consume all horizontal width not consumed by columns with a specified width).

In my case, I wanted the left-most column to be automatically sized, because all of the rest of the columns having a size specified. I was looking for a simple way to implement this, and came up with the following. Handle the SizeChanged event for the ListView, and in the event handler method, and implement code that looks something like this:

private void InnerListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (e.WidthChanged)
    {
        GridView view  = this.InnerListView.View as GridView;
        Decorator border = VisualTreeHelper.GetChild(this.InnerListView, 0) as Decorator;
        if (border != null)
        {
            ScrollViewer scroller = border.Child as ScrollViewer;
            if (scroller != null)
            {
                ItemsPresenter presenter = scroller.Content as ItemsPresenter;
                if (presenter != null)
                {
                    view.Columns[0].Width = presenter.ActualWidth;
                    for (int i = 1; i < view.Columns.Count; i++)
                    {
                        view.Columns[0].Width -= view.Columns[i].ActualWidth;
                    }
                }
            }
        }
    }
}


Because a ListView could have enough items to cause the vertical scrollbar to be displayed, we have to account for this in a non hard-wired manner. Essentially, you want to find the width of the "client rectangle" (to put it into a Windows API context), which excludes the vertical scrollbar's width. To accomplish this, we need to get to the ItemsPresenter control inside the ListView.

In a standard ListView, the Child is a Decorator, and the ScrollViewer is the Child of Decorator. Finally, the ItemsPresenter is the Content of the ScrollViewer, and guess what - ItemsPresenter.ActualWidth represents the width of your ListView content NOT INCLUDING the scrollbar's width. Will wonders never cease?

Once you get the width of your client area, you can loop through all of the columns and subtract their width to come up with a hard-wired width for your "*" column.

Notice - I realize there are probably more WPF-conformant techniques to accomplish this goal, but I am more interested in "getting the work done" than in strictly adhering to a programming paradigm. I also don't really care to work in XAML.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
QuestionJust the ticket Pin
Mike Hankey20-Jul-23 10:07
mveMike Hankey20-Jul-23 10:07 
BugWidth keeps increasing Pin
Paul Hildebrandt4-Aug-13 18:58
Paul Hildebrandt4-Aug-13 18:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.