1

I am storing column widths on application exit and restore them on startup. Everything works fine unless user double click header. This would cause column width become double.NaN which I understood is a flag for autosizing. Then I have problems.

While investigating the issue I noticed what setting column width to NaN will enable auto-resizing but only for one time.

Here is a repro:

<ListView x:Name="listView">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="A" Width="NaN" />
        </GridView>
    </ListView.View>
</ListView>

Then add two buttons with following click handlers:

void button1_Click(object sender, RoutedEventArgs e) => listView.Items.Add("abcd");
void button2_Click(object sender, RoutedEventArgs e) => listView.Items.Add("ABCDEFGHIJKL");

Clicking button1 first will autosize column to fit "abcd". Clicking then button2 won't.

Why? Is there a workaround to have it either always autosizing or to at least disable user double-click resizing (tried this solution without success)?

Community
  • 1
  • 1
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Does `Width="Auto"` instead of `NaN` not work? – TyCobb Mar 08 '17 at 16:09
  • This prevents the user from being able to resize the columns: http://stackoverflow.com/questions/181956/prevent-user-from-resizing-columns-with-wpf-listview – mm8 Mar 08 '17 at 16:10
  • @TyCobb, `GridLength.Auto` is for `Grid`'s [`ColumnDefinition.Width`](https://msdn.microsoft.com/en-us/library/system.windows.controls.columndefinition.width(v=vs.110).aspx). Here `GridViewColumn.Width` is of `double` type. – Sinatr Mar 08 '17 at 16:17
  • @mm8, I don't want to prevent user from resizing ;) Only from that *very special* (`double.NaN` lol) double-click auto-resizing. – Sinatr Mar 08 '17 at 16:18
  • @Sinatr Got it. I was looking at this question where the answer had the widths set as auto which I thought could fit your *have it ether always autosizing* http://stackoverflow.com/questions/560581/how-to-autosize-and-right-align-gridviewcolumn-data-in-wpf – TyCobb Mar 08 '17 at 16:19
  • See also https://stackoverflow.com/questions/6307289/wpf-gridviewcolumn-width-auto-only-works-for-items-in-the-current-scroll-scope/6308331 when just the initial width is not properly computed. – PMF Jul 30 '19 at 09:22

2 Answers2

3

You need to reset the Width of the column on each update:

void button2_Click(object sender, RoutedEventArgs e)
{
    listView.Items.Add("ABCDEFGHIJKL");
    GridView gv = listView.View as GridView;
    gv.Columns[0].Width = gv.Columns[0].ActualWidth;
    gv.Columns[0].Width = double.NaN;

}

And to disable double-click resizing you could handle the PreviewMouseLeftButtonDown event for the GridViewColumnHeader like this:

<ListView x:Name="listView">
    <ListView.View>
        <GridView>
            <GridView.ColumnHeaderContainerStyle>
                <Style TargetType="{x:Type GridViewColumnHeader}">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="listView_PreviewMouseLeftButtonDown"/>
                </Style>
            </GridView.ColumnHeaderContainerStyle>
            <GridViewColumn Header="A" Width="Auto" />
        </GridView>
    </ListView.View>
</ListView>

private void listView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) =>
    e.Handled = e.ClickCount == 2;
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Seems to work. That's a dirty trick (setting value to current actual width and then again to `NaN`), I'd never thought to do so. Disabling also works, two answers in one, thanks! – Sinatr Mar 08 '17 at 16:31
3

This is a well know behaviour of the WPF GridView.

A generic solution for multiple columns is to register an event handler (my personal suggestion is for SizeChanged)

<ListView x:Name="listView" SizeChanged="listView_SizeChanged">

to do the update

private void listView_SizeChanged(object sender, SizeChangedEventArgs e)
{
    foreach (GridViewColumn c in ((GridView)listView.View).Columns)
    {
        if (double.IsNaN(c.Width))
        {
            c.Width = c.ActualWidth;
        }
        c.Width = double.NaN;
    }
}
Community
  • 1
  • 1
  • 2
    typical absurd downvote: this is how at SO they guarantee the quality of answers :-) –  Mar 08 '17 at 20:41