Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 强制调整ListView中GridView列的大小_C#_.net_Wpf_Listview - Fatal编程技术网

C# 强制调整ListView中GridView列的大小

C# 强制调整ListView中GridView列的大小,c#,.net,wpf,listview,C#,.net,Wpf,Listview,我有一个带有GridView的ListView WPF控件。我想在列的内容更改时调整GridView列的大小 我有几个不同的数据集,但是当我从一个数据集更改到另一个数据集时,每列的大小都与以前的数据相匹配。我想动态更新。如何才能做到这一点?您可以测量以像素为单位的最长字符串,然后相应地调整列宽: Graphics graphics = this.CreateGraphics(); SizeF textSize = graphics.MeasureString("How long am I?",

我有一个带有GridView的ListView WPF控件。我想在列的内容更改时调整GridView列的大小


我有几个不同的数据集,但是当我从一个数据集更改到另一个数据集时,每列的大小都与以前的数据相匹配。我想动态更新。如何才能做到这一点?

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

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

如果您创建一个算法,根据这些长度的比率调整每列的大小,您应该会得到一个好的结果。

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

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

如果您创建一个算法,根据这些长度的比率来调整每个列的大小,您应该会得到一个好的结果。

最后,在这个问题上会有一些结果。我已经找到了一种方法,可以在双击列标题上的夹持器时自动调整大小

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

最后,本文给出了一些结果。我已经找到了一种方法,可以在双击列标题上的夹持器时自动调整大小

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

有没有办法绑定到列的实际宽度?比如:

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

我已经试过了,但它似乎只是第一次起作用。没有绑定错误。

是否有方法绑定到列的实际宽度?比如:

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

我已经试过了,但它似乎只是第一次起作用。没有绑定错误。

建立在奥斯卡答案之上,这里有一个混合行为,可以在内容更改时自动调整列的大小

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

在Oskar answer的基础上,这里有一个混合行为,可以在内容更改时自动调整列的大小

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

如果你像我一样老了,喜欢VB.NET,那么下面是奥斯卡代码:

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中非常有效,终于有人解决了这个问题。谢谢奥斯卡。

如果你像我一样老了,更喜欢VB.NET,那么奥斯卡代码如下:

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中非常有效,终于有人解决了这个问题。谢谢奥斯卡。

我也有同样的问题。更改数据源,列宽不会调整大小。我很乐意设置源代码并调用AutoSizeColumns方法或类似方法。我也有同样的问题。更改数据源,列宽不会调整大小。我很乐意设置源代码并调用AutoSizeColumns方法或类似方法。我也尝试过:Width={Binding Path=ActualWidth,RelativeSource={x:Static RelativeSource.Self}}}是的,将ActualWidth复制到Width,这将永远是预期的宽度。第一次禁用自动调整大小。然后,实际宽度再也不会改变,因此预期宽度也不会改变。我也尝试过:宽度={Binding Path=ActualWidth,RelativeSource={x:Static RelativeSource.Self}}}是的,将实际宽度复制到宽度,这将永远是预期宽度。第一次禁用自动调整大小。实际宽度将不再改变,因此预期宽度也不会改变。很好的解决方案。谢谢,很好的解决方案。谢谢。此行为没有考虑到在计算新的实际宽度之前可能需要一些时间。因此,实际宽度可能仍然太小,无法容纳内容物。@Danielku15您发现了吗?一个小样本将非常好,这样我就可以解决这个问题。我有一个绑定到ObservableCollection的ListView。我的CellTemplate中有一个控件是40x40pt。附加该行为将执行OnListViewItemsCollectionChanged方法,但在我的示例中,实际宽度仍然太小。结果是:它被裁剪了。似乎在执行处理程序时layoutprocess没有运行。与@Danielku15类似,我有一个ListViewBehavior类,它在ListView.ItemsChanged事件处理程序中实现了ActualWidth、Double.NaN更改。将绑定的源属性设置为新的项集合时,会计算自动列,但会在稍后的未知时间进行,因此无法调整填充列的大小&列溢出ListView宽度。删除这些行和自动列是按预期计算的,并且完全符合ListView宽度,但它们不是按新内容计算的。此行为没有考虑到在计算新的实际宽度之前可能需要一段时间。因此,实际宽度可能仍然太小,无法容纳内容物。@Danielku15您发现了吗?一个小样本将非常好,这样我就可以解决这个问题。我有一个绑定到ObservableCollection的ListView。我的CellTemplate中有一个控件是40x40pt。附加该行为将执行OnListViewItemsCollectionChanged方法,但在我的示例中,实际宽度仍然太小。结果是:它被裁剪了。似乎在执行处理程序时layoutprocess没有运行。与@Danielku15类似,我有一个ListViewBehavior类,它在ListView.ItemsChanged事件处理程序中实现了ActualWidth、Double.NaN更改。将绑定源属性设置为新coll时 项的节,自动列是计算出来的,但在以后未知的时间,所以我无法调整填充列的大小&列溢出了ListView的宽度。删除这些行和自动列会在需要时进行计算,并与ListView宽度完全匹配,但不会根据新内容进行计算。