ListView AutoResizeColumns基于列内容和标题

我们使用这两种方法根据列内容和标题resp调整列长度。

ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

但是如何根据两者进行调整? 即调整为标题和列内容的最长长度。

lvw.Columns[0].Width = -2

有关详细信息,请参阅MSDN中的备注: http : //msdn.microsoft.com/en-us/library/system.windows.forms.columnheader.width.aspx

另请注意,MSDN说’要自动调整到列标题的宽度,请将Width属性设置为-2。’,但实际上它适用于列标题和列内容。

这是一个代码来certificate:

  lvw.Columns.Add(new String('x', 25)); // short header lvw.Items.Add(new String('x', 100)); // long content lvw.Columns[0].Width = -2; // in result column width will be set to fit content 

正如这里所回答的,调用两个resize选项都可以完成工作

 myListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); myListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 

这是我用来调整内容和标题的列宽:

 public static void autoResizeColumns(ListView lv) { lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); ListView.ColumnHeaderCollection cc = lv.Columns; for (int i = 0; i < cc.Count; i++) { int colWidth = TextRenderer.MeasureText(cc[i].Text, lv.Font).Width + 10; if (colWidth > cc[i].Width) { cc[i].Width = colWidth; } } } 

使用示例:

 autoResizeColumns(listView1); 

该方法不是经过充分测试,但至少它在我正在使用它的上下文中工作。

确实可以使用MeasureText然后计算剩余多少空间并以某种方式在所有列之间分配。 但这是我快速编写的快速而肮脏的方法:

  ///  /// Enables autoresizing for specific listview. /// You can specify how much to scale in columnScaleNumbers array - length of that array /// should match column count which you have. ///  /// control for which to enable auto-resize /// Percentage or numbers how much each column will be scaled. private void EnableAutoresize(ListView listView, params int[] columnScaleNumbers) { listView.View = View.Details; for( int i = 0; i < columnScaleNumbers.Length; i++ ) { if( i >= listView.Columns.Count ) break; listView.Columns[i].Tag = columnScaleNumbers[i]; } listView.SizeChanged += lvw_SizeChanged; DoResize(listView); } void lvw_SizeChanged(object sender, EventArgs e) { ListView listView = sender as ListView; DoResize(listView); } bool Resizing = false; void DoResize( ListView listView ) { // Don't allow overlapping of SizeChanged calls if (!Resizing) { // Set the resizing flag Resizing = true; if (listView != null) { float totalColumnWidth = 0; // Get the sum of all column tags for (int i = 0; i < listView.Columns.Count; i++) totalColumnWidth += Convert.ToInt32(listView.Columns[i].Tag); // Calculate the percentage of space each column should // occupy in reference to the other columns and then set the // width of the column to that percentage of the visible space. for (int i = 0; i < listView.Columns.Count; i++) { float colPercentage = (Convert.ToInt32(listView.Columns[i].Tag) / totalColumnWidth); listView.Columns[i].Width = (int)(colPercentage * listView.ClientRectangle.Width); } } } // Clear the resizing flag Resizing = false; } 

根据您拥有的列数 - 您可以指定每列“百分比”或简单编号。 例如,对于3列 - 调用如下所示:

  EnableAutoresize(listView1, 6, 3, 1); 

这将分配列大小:第一列为6 * 100%/(6 + 3 + 1)= 60%,下一列为30%,剩余为10%。

这在某种程度上是穷人快速实施。 🙂

在我的例子中,我通过接下来的步骤(对于两列数据)执行此操作:

  1. 为每列创建ColumnHeader对象。
  2. 基于HeaderSize(在两列上)通过AutoResize设置大小
  3. 将该值存储在Integer变量中
  4. 根据ColumnContent(在两列上)通过AutoResize设置大小
  5. 通过旧值和新值(对于每列)之间的Max条件更新每个Integer变量的值。
  6. 设置每个ColumnHeader对象的列宽大小。

在VB.NET中:

 'Create two header objects as ColumnHeader Class Dim header1, header2 As ColumnHeader 'Construcción de los objetos header header1 = New ColumnHeader header1.Text = "ID" header1.TextAlign = HorizontalAlignment.Right header1.Width = 10 header2 = New ColumnHeader header2.Text = "Combinaciones a Procesar" header2.TextAlign = HorizontalAlignment.Left header2.Width = 10 'Add two columns using your news headers objects ListView.Columns.Add(header1) ListView.Columns.Add(header2) 'Fill three rows of data, for each column ListView.Items.Add(New ListViewItem({"A1", "B1"})) ListView.Items.Add(New ListViewItem({"A2", "B2"})) ListView.Items.Add(New ListViewItem({"A3", "B3"})) 'Change the size of each column Dim headsz1, headsz2 As Integer SelectionInTable.ListView.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.HeaderSize) SelectionInTable.ListView.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.HeaderSize) headsz1 = header1.Width headsz2 = header2.Width SelectionInTable.ListView.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent) SelectionInTable.ListView.AutoResizeColumn(1, ColumnHeaderAutoResizeStyle.ColumnContent) headsz1 = Math.Max(headsz1, header1.Width) headsz2 = Math.Max(headsz2, header2.Width) header1.Width = headsz1 header2.Width = headsz2 

这是一个可以用于任何ListView的C#解决方案。 它假定您的列数和标题不会因任何给定的列表视图而改变。 如果要每次重新计算标题宽度(如果标题更改或列数更改),请删除listViewHeaderWidths字典。

  private Dictionary listViewHeaderWidths = new Dictionary(); private void ResizeListViewColumns(ListView lv) { int[] headerWidths = listViewHeaderWidths.ContainsKey(lv.Name) ? listViewHeaderWidths[lv.Name] : null; lv.BeginUpdate(); if (headerWidths == null) { lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); headerWidths = new int[lv.Columns.Count]; for (int i = 0; i < lv.Columns.Count; i++) { headerWidths[i] = lv.Columns[i].Width; } listViewHeaderWidths.Add(lv.Name, headerWidths); } lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); for(int j = 0; j < lv.Columns.Count; j++) { lv.Columns[j].Width = Math.Max(lv.Columns[j].Width, headerWidths[j]); } lv.EndUpdate(); } 

Anton Kedrov回答是最好的一个,但在我的情况下,我有一个列表视图超过50列,我经常更新其数据在这种情况下,我注意listview的this.AutoResizeColumns执行更快的工作,所以我写这个解决方案也

第一种方法,设置为-2

 public void AutoUpdateColumnWidth(ListView lv) { for (int i = 0; i <= lv.Columns.Count - 1; i++) { lv.Columns(i).Width = -2; } } 

我使用的第二种方法(多次调用时闪烁较少)

 public void AutoUpdateColumnWidth(ListView lv) { ListViewItem nLstItem = new ListViewItem(lv.Columns(0).Text); for (int i = 1; i <= lv.Columns.Count - 1; i++) { nLstItem.SubItems.Add(lv.Columns(i).Text); } v.Items.Add(nLstItem); lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); lv.Items.RemoveAt(nLstItem.Index); } 

这很简单(虽然我需要一段时间来弄明白)……

我们知道宽度必须至少与列标题一样大,以便我们看到所有标题文本。 除此之外,宽度可以扩大以容纳内容。 因此,我们执行以下操作:

  1. 将列自动调整为标题。
  2. 遍历列并将每列的最小宽度属性设置为当前列宽(这可确保您的列永远不会太小而无法看到标题)。
  3. 从现在开始,按内容自动调整列。

没有必要单独跟踪宽度并将其重置为其他海报建议的。 设置列的最小宽度可解决问题,直到更改标题文本为止,在这种情况下,您将最小宽度设置为0,仅自动调整已修改的列,然后再次将最小宽度设置为当前宽度。

编辑:道歉,我忘了我没有使用标准列表视图,而是第三方产品BetterListView(免费版本可用)。 标准列表视图列似乎不支持最小宽度。 我确实推荐BetterListView作为一个很好的选择(更好的function集和性能)。