2

In WPF, I have the following:

<ListView.View>
    <GridView>
        <GridViewColumn
            Width="Auto"
            DisplayMemberBinding="{Binding SomeProperty, Mode=OneWay}"
            Header="Type"/>

The problem is that this only auto-sizes the column to the visible content. This is the same behavior when double clicking the header divider as well.

I want it to resize the column according to all content. For contrast, take the Winforms DataGridView equivalent to the current Auto resizing behavior and the equivalent to the desired behavior:

this.dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; // Current behavior
this.dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;       // Desired behavior

Is this possible for a WPF ListView?

This question is different than How to autosize and right-align GridViewColumn data in WPF? and others like it because they still trigger the current resizing behavior for visible content and do not address all content.

Community
  • 1
  • 1
OhBeWise
  • 5,350
  • 3
  • 32
  • 60

1 Answers1

3

The problem is the ListView has its ItemsPanel with virtualizing enabled by default. In this mode, only visible content will be rendered and then will trigger the auto-sizing column. So if you don't have many items in your ListView, you can turn off the virtualizing mode via the attached property VirtualizingStackPanel.IsVirtualizing, then it will work expectedly:

<ListView VirtualizingStackPanel.IsVirtualizing="false">
       <!-- ... -->
</ListView>

If you don't want to turn off virtualizing, then I don't think there is some easy way to take benefit of the Width="Auto". You may have to implement that feature manually yourself. And technically we need to have knowledge about the largest width to update the column's width accordingly. We can make some for loop every time we need to update the column's width but this is expensive. We can also manage to store the largest width every time a cell has its content changed (this is the better approach). Anyway doing it manually is a pain.

Hopeless
  • 4,397
  • 5
  • 37
  • 64
  • Setting `IsVirtualizing` to `False` didn't do anything. Did you mean that this had to be done in addition to the manual resize? – OhBeWise Sep 30 '15 at 15:36
  • @OhBeWise it's strange that it works for me. If it does not work for you then I have no idea. You can try finding some other approach instead. Of course I'm not really interested in any other approach at the moment, at least this already works for me so I'll use this whenever I encounter the same issue. For your question, you don't need to resize manually, just set `IsVirtualizing` to false. BTW: auto-resizing here works initially only, if you have any data ***updated/added at runtime***, I'm not sure if it works (did not test that scenario). – Hopeless Sep 30 '15 at 15:55
  • After some additional testing, I've discovered that generally your solution is correct. However, I have an attached Behavior class similar to [this ListView Layout Manager](http://www.codeproject.com/Articles/25058/ListView-Layout-Manager) which sadly, for some reason or the other, stops this from working. – OhBeWise Sep 30 '15 at 16:08
  • 1
    As it turns out, the error for me is very specific to setting a `MinWidth` and/or `MaxWidth` in the ListView Behavior class for the specified GridViewColumn - which is something I'll just have to figure out. Thanks for the solution! – OhBeWise Sep 30 '15 at 16:52