强制在ListView中调整GridView列的大小

时间:2009-05-10 12:45:10

标签: c# .net wpf listview

我有ListView WPF控件,GridView。当列的内容发生变化时,我想调整GridView列的大小。

我有几个不同的数据集但是当我从一个更改为另一个时,每列的大小适合以前的数据。我想动态更新。我怎么能这样做?

5 个答案:

答案 0 :(得分:29)

最后,对此有一些结果。我找到了一种方法来执行相同的自动调整大小,最初完成时以及双击列标题上的抓手时。

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;
        }
    }
}

答案 1 :(得分:4)

在Oskars答案的基础上,这是一种混合行为,可在内容发生变化时自动调整列的大小。

 /// <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();
      }
 }

答案 2 :(得分:1)

是否有办法绑定到列的ActualWidth?类似的东西:

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

我试过这个,它似乎只是第一次起作用。没有绑定错误。

答案 3 :(得分:1)

如果像我一样,你老了,更喜欢VB.NET,那么这里是Oskars代码:

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

这在WPF中很有用,最后有人解决了这个问题。谢谢奥斯卡。

答案 4 :(得分:-1)

您可以测量最长的字符串(以像素为单位),然后相应地调整列宽:

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

如果您创建一个算法来确定每个列的大小,这些长度的比例,您应该会得到一个好的结果。