Force resize of GridView columns inside ListView

后端 未结 5 1744
Happy的楠姐
Happy的楠姐 2020-12-10 02:07

I have a ListView WPF control with a GridView. I\'d like to resize the GridView columns when the content of the columns changes.

相关标签:
5条回答
  • Building on top of Oskars answer, here is a blend behavior to automatically size the columns when the content changes.

     /// <summary>
     /// A <see cref="Behavior{T}"/> implementation which will automatically resize the automatic columns of a <see cref="ListView">ListViews</see> <see cref="GridView"/> to the new content.
     /// </summary>
     public class GridViewColumnResizeBehaviour : Behavior<ListView>
     {
          /// <summary>
          /// Listens for when the <see cref="ItemsControl.Items"/> collection changes.
          /// </summary>
          protected override void OnAttached()
          {
              base.OnAttached();
    
              var listView = AssociatedObject;
              if (listView == null)
                  return;
    
              AddHandler(listView.Items);
          }
    
          private void AddHandler(INotifyCollectionChanged sourceCollection)
          {
              Contract.Requires(sourceCollection != null);
    
              sourceCollection.CollectionChanged += OnListViewItemsCollectionChanged;
          }
    
          private void RemoveHandler(INotifyCollectionChanged sourceCollection)
          {
              Contract.Requires(sourceCollection != null);
    
              sourceCollection.CollectionChanged -= OnListViewItemsCollectionChanged;
          }
    
          private void OnListViewItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
          {
              var listView = AssociatedObject;
              if (listView == null)
                  return;
    
              var gridView = listView.View as GridView;
              if (gridView == null)
                  return;
    
              // If the column is automatically sized, change the column width to re-apply automatic width
              foreach (var column in gridView.Columns.Where(column => Double.IsNaN(column.Width)))
              {
                   Contract.Assume(column != null);
                   column.Width = column.ActualWidth;
                   column.Width = Double.NaN;
              }
          }
    
          /// <summary>
          /// Stops listening for when the <see cref="ItemsControl.Items"/> collection changes.
          /// </summary>
          protected override void OnDetaching()
          {
              var listView = AssociatedObject;
              if (listView != null)
                  RemoveHandler(listView.Items);
    
              base.OnDetaching();
          }
     }
    
    0 讨论(0)
  • Isn't there a way to bind to the ActualWidth of the column? Something like :

    <GridViewColumn x:Name="column1" Width="{Binding ElementName=column1, Path=ActualWidth}" />
    

    I have tried this and it works only the first time, it seems. No binding error.

    0 讨论(0)
  • 2020-12-10 02:45

    Finally, some results on this one. I've found a way to do the same auto-sizing that is done initially and when the gripper on a column header is double clicked.

    public void AutoSizeColumns()
    {
        GridView gv = listView1.View as GridView;
        if (gv != null)
        {
            foreach (var c in gv.Columns)
            {
                // Code below was found in GridViewColumnHeader.OnGripperDoubleClicked() event handler (using Reflector)
                // i.e. it is the same code that is executed when the gripper is double clicked
                if (double.IsNaN(c.Width))
                {
                    c.Width = c.ActualWidth;
                }
                c.Width = double.NaN;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 02:48

    If like me you are old and prefer VB.NET then here's Oskars code:

    Public Sub AutoSizeColumns()
        Dim gv As GridView = TryCast(Me.listview1.View, GridView)
        If gv IsNot Nothing Then
            For Each c As GridViewColumn In gv.Columns
                If Double.IsNaN(c.Width) Then
                    c.Width = c.ActualWidth
                End If
                c.Width = Double.NaN
            Next
        End If
    End Sub
    

    This works great in WPF, finally someone has worked this out. Thanks Oskar.

    0 讨论(0)
  • 2020-12-10 02:51

    You could measure the longest string in pixels and then adjust the column widths accordingly:

    Graphics graphics = this.CreateGraphics();
    SizeF textSize = graphics.MeasureString("How long am I?", this.Font);
    

    If you create an algorithm for sizing each column as a ratio of these lengths, you should get a good result.

    0 讨论(0)
提交回复
热议问题