如何自动调整DataGridView控件中的列并允许用户调整同一网格上的列的大小?

时间:2009-06-22 06:10:04

标签: c# winforms datagridview

我正在Windows窗体上填充DataGridView控件(C#2.0而不是WPF)。

我的目标是显示一个整齐地填充所有可用宽度的网格 - 即右侧没有未使用的(深灰色)区域,并根据其包含的数据适当地调整每列的大小,还允许用户根据自己的喜好调整任何列的大小。

我试图通过将每列的AutoSizeMode设置为 DataGridViewAutoSizeColumnMode.AllCells 来实现此目的,除了我设置为 DataGridViewAutoSizeColumnMode.Fill 之一的列之一确保整个网格区域整齐地填充数据。 (我不介意当用户尝试调整此列的大小时,它会弹回一个确保始终使用水平空间的大小。)

但是,正如我所提到的,一旦加载,我想允许用户调整列的大小以满足他们自己的要求 - 在为每个列设置这些AutoSizeMode值时,用户就无法再调整这些列的大小。 / p>

我尝试不设置允许调整大小的所有列的AutoSizeMode但是根据单元格包含的数据不设置初始大小。加载数据后将网格的AutoSizeMode更改回“未设置”时会出现相同的结果。

我是否缺少一个允许自动设置默认列宽和用户调整大小的设置,还是在填充DataGridView控件时必须使用另一种技术?

24 个答案:

答案 0 :(得分:120)

这个技巧对我有用:

grd.DataSource = DT;

//set autosize mode
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= grd.Columns.Count - 1; i++) {
    //store autosized widths
    int colw = grd.Columns[i].Width;
    //remove autosizing
    grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    //set width to calculated by autosize
    grd.Columns[i].Width = colw;
}

这里发生的是你将自动调整大小设置为你需要的模式,然后逐列存储从自动调整计算得到的宽度,删除自动调整大小并将宽度设置为之前存储的值。

答案 1 :(得分:41)

也许你可以打电话

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

设置数据源后。它将设置宽度并允许调整大小。

有关MSDN DataGridView.AutoResizeColumns Method (DataGridViewAutoSizeColumnsMode)的更多信息。

答案 2 :(得分:29)

Miroslav Zadravec代码的C#版本

for (int i = 0; i < dataGridView1.Columns.Count-1; i++)
{
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
    int colw = dataGridView1.Columns[i].Width;
    dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dataGridView1.Columns[i].Width = colw;
}

作为社区Wiki发布,以免偏离其他人的声誉

答案 3 :(得分:12)

在我的应用程序中,我已经设置了

grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;

另外,我已经设置了

grid.AllowUserToOrderColumns = true;
grid.AllowUserToResizeColumns = true;

现在可以更改列宽,用户可以重新排列列。这对我很有用。

也许这对你有用。

答案 4 :(得分:8)

好吧,我是这样做的:

dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvReport.AutoResizeColumns();
dgvReport.AllowUserToResizeColumns = true;
dgvReport.AllowUserToOrderColumns = true;

按特定顺序排列。列的大小调整(扩展),然后用户可以调整列的大小。

答案 5 :(得分:8)

将数据添加到网格后,添加以下代码,根据每个单元格中的数据长度调整列

dataGrid1.AutoResizeColumns();            
dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

这是结果

enter image description here

答案 6 :(得分:6)

如果我正确地理解了这个问题,应该有一种更简单的方法来完成你所需要的。呼叫 dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

这应该可以解决问题。但是,有一个缺陷,因为在填充DataGridView控件后不能直接调用此方法。相反,您必须为VisibleChanged事件添加一个EventHandler并在那里调用该方法。

答案 7 :(得分:4)

问题的简历:
列宽适应内容(在列中使用不同的方法),
但然后允许用户设置列宽...

Miroslav Zadravec's answer开发,对我来说有用的是立即使用自动计算column.Width来设置... column.Width

foreach (DataGridViewColumn column in dataGridView.Columns)
{
    if (/*It's not your special column*/)
    {
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        column.Width = column.Width; //This is important, otherwise the following line will nullify your previous command
        column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
    }
}

//Now do the same using Fill instead of AllCells for your special column

使用像this这样的技巧,在已经创建DataGridView的情况下对此进行了测试。

答案 8 :(得分:3)

这给我带来了奇迹:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

答案 9 :(得分:2)

Miroslav Zadravec的另一个版本的代码,但略微更自动化和通用:

    public Form1()
    {
        InitializeComponent();
        dataGridView1.DataSource = source;
        for (int i = 0; i < dataGridView1.Columns.Count - 1; i++) {
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
        }
        dataGridView1.Columns[dataGridView1.Columns.Count].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

    }

    void Form1Shown(object sender, EventArgs e)
    {
        for ( int i = 0; i < dataGridView1.Columns.Count; i++ )
        {
            int colw = dataGridView1.Columns[i].Width;
            dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            dataGridView1.Columns[i].Width = colw;
        }
    }

我将第二部分放入单独的事件中,因为我在表单的初始化中填充datagridvew,如果两个部分都存在,则没有任何变化,因为可能自动调整大小会在datagridview显示后计算宽度,因此宽度仍然是Form1()方法中的默认值。在完成此方法之后,自动调整大小完成其技巧并在此之后(当显示表单时),我们可以通过代码的第二部分(此处为Form1Shown事件)设置宽度。这对我来说就像一个魅力。

答案 10 :(得分:2)

简单的两行代码对我有用。

dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();

答案 11 :(得分:2)

以下是Miroslav Zadravec在c#中的答案的简化代码:

CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
for (int i = 0; i < dataGridView1.Columns.Count; i++) dataGridView1.Columns[i].Width = dataGridView1.Columns[i].Width;
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;

答案 12 :(得分:2)

这会根据内容自动调整所有列,通过拉伸指定的列填充剩余的空白空间,并通过将最后一列设置为以后任何调整大小来阻止“跳跃”行为。

// autosize all columns according to their content
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
// make column 1 (or whatever) fill the empty space
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
// remove column 1 autosizing to prevent 'jumping' behaviour
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// let the last column fill the empty space when the grid or any column is resized (more natural/expected behaviour) 
dgv.Columns.GetLastColumn(DataGridViewElementStates.None, DataGridViewElementStates.None).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

答案 13 :(得分:2)

Miroslav Zadravec的代码中稍微整洁的C#代码,假设所有列都要自动调整

for (int i = 0; i < dgvProblems.Columns.Count; i++)
{
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    int colw = dgvProblems.Columns[i].Width;
    dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgvProblems.Columns[i].Width = colw;
}

答案 14 :(得分:1)

列宽设置为适合其内容我使用了下面的声明, 它解决了我的问题。

第一步:

RadGridViewName.AutoSize = true;

第二步:

// This mode  fit in the header text and column data for all visible rows. 
this.grdSpec.MasterTemplate.BestFitColumns();

第三步:

for (int i = 0; i < grdSpec.Columns.Count; i++) 
{
    // The column width adjusts to fit the contents all cells in the control.
    grdSpec.Columns[i].AutoSizeMode = BestFitColumnMode.AllCells; 
}

答案 15 :(得分:1)

dataGridView1.AutoResizeColumns();

答案 16 :(得分:1)

Schnapple版本的一点改进

int nLastColumn = dgv.Columns.Count - 1;
for (int i = 0; i < dgv.Columns.Count; i++)
{
    if (nLastColumn == i)
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    else
    {
        dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
}

for (int i = 0; i < dgv.Columns.Count; i++)
{
    int colw = dgv.Columns[i].Width;
    dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    dgv.Columns[i].Width = colw;
}

答案 17 :(得分:1)

您是否尝试设置FillWeight对象的DataGridViewColumns属性?

例如:

this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.grid1.Columns[0].FillWeight = 1.5;

我认为它适用于你的情况。

答案 18 :(得分:0)

例如,如果将数据源绑定到数据表,则需要在绑定完成后设置属性:

        private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.AutoResizeColumns();
            dgv.AllowUserToResizeColumns = true;
        }

答案 19 :(得分:0)

  • 感谢上面的解决方案(要遍历DataGridView.Columns,将AutoSizeMode更改为有效的,收集宽度值并在将AutoSizeMode更改为DataGridViewAutoSizeColumnMode.None后将其设置回来)。
  • 我很挣扎,并注意到从类构造函数或Form.Show()Form.ShowDialog()之前的任何行调用它时都无效。所以我将此代码段放在Form.Shown事件中,这对我有用。
  • 我转换后的代码,不管之前设置的DataGridView.AutoSizeColumnsMode是什么,我使用DataGridViewColumn.GetPreferredWidth()而不是更改DataGridViewColumn.AutoSizeMode并立即设置宽度值,然后更改DataGridView.AutoSizeColumnsMode曾经:

    private void form_Shown(object sender, EventArgs e)
    {
            foreach (DataGridViewColumn c in dataGridView.Columns)
                c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true);
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
    }
    
  • 请务必设置

            dataGridView.AllowUserToResizeColumns = true;
    
  • 我不知道为什么这只会在表格显示后才有效。

答案 20 :(得分:0)

foreach (DataGridViewColumn c in dataGridView.Columns)
    c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);

无论dataGridView是否已显示(即使从类构造函数调用),这都应该有效。

同样的方法,但DataGridViewAutoSizeColumnMode.DisplayedCells,在上述情况下失败的原因显而易见 - 尚未显示任何单元格!出于某些非显而易见的原因,AutoResizeColumns在这种情况下也会失败。

答案 21 :(得分:0)

我必须在VB中执行此操作,并且更喜欢将其拆分为我放置在模块中的方法。如果需要,可以将Fill列添加为另一个ByRef参数。

''' <summary>
''' Makes all columns in a DataGridView autosize based on displayed cells,
''' while leaving the column widths user-adjustable.
''' </summary>
''' <param name="dgv">A DataGridView to adjust</param>
Friend Sub MakeAdjustableAutoSizedGridCols(ByRef dgv As DataGridView)
    Dim width As Integer

    For Each col As DataGridViewColumn In dgv.Columns
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
        width = col.Width
        col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
        col.Width = width
    Next
    dgv.AllowUserToResizeColumns = True
End Sub

答案 22 :(得分:0)

您可以执行以下操作:

   grd.DataSource = getDataSource();

    if (grd.ColumnCount > 1)
    {
        for (int i = 0; i < grd.ColumnCount-1; i++)
            grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;

        grd.Columns[grd.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }

    if (grd.ColumnCount==1)
        grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

所有列将适应内容,最后一行将填充网格。

答案 23 :(得分:0)

使用$ array作为PSCustomObject的内容,它可以正常工作:

$dataGridView1.DataSource=[collections.arraylist]($array)
$dataGridView1.Columns | Foreach-Object{$_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells}