Как вы автоматически изменяете размер столбцов в элементе управления DataGridView? И разрешить пользователю изменять размеры столбцов в той же сетке?

Я заполняю элемент управления DataGridView в форме Windows (С# 2.0, а не WPF).

Моя цель состоит в том, чтобы отображать сетку, которая аккуратно заполняет всю доступную ширину ячейками, т.е. не содержит неиспользуемых (темно-серых) областей справа и размер каждого столбца соответственно в соответствии с содержащимися в нем данными, , но также позволяет пользователю изменять размер любого из столбцов по своему вкусу.

Я пытаюсь добиться этого, установив AutoSizeMode каждого столбца DataGridViewAutoSizeColumnMode.AllCells, за исключением одного из столбцов, которые я установил в DataGridViewAutoSizeColumnMode.Fill, чтобы упорядочить чтобы вся область сетки была аккуратно заполнена данными. (Я не возражаю, что, когда пользователь пытается изменить размер этого столбца, он возвращается к размеру, который гарантирует, что горизонтальное пространство всегда используется.)

Однако, как я уже упоминал, после загрузки я хотел бы разрешить пользователю изменять размеры столбцов в соответствии с их собственными требованиями - при установке этих значений AutoSizeMode для каждого столбца он появляется, тогда пользователь не может изменить размер этих столбцов.

Я пробовал не устанавливать AutoSizeMode всех столбцов, которые позволяют изменять размер, но не устанавливает начальный размер в соответствии с данными, содержащими ячейки. Тот же результат возникает при замене сетки AutoSizeMode на "Not Set" после загрузки данных.

Есть ли здесь параметр, который позволяет автоматически устанавливать ширину столбцов по умолчанию и изменение размера пользователя или есть ли другой метод, который я должен использовать при заполнении элемента управления DataGridView?

Ответ 1

Этот трюк работает для меня:

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

Что здесь происходит, так это то, что вы устанавливаете autosize в какой бы тобой режим, а затем столбец по столбцу, вы храните полученную им ширину от вычисления автозапуска, удаляете автосоздание и устанавливаете ширину для значения, которое вы ранее сохраняли.

Ответ 2

Возможно, вы могли бы позвонить

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

После установки источника данных. Он установит ширину и позволит изменить размер.

Подробнее о MSDN Метод DataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode).

Ответ 3

Версия С# кода Мирослава Задравеца

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

Размещено как Community Wiki, чтобы не отмахиваться от репутации других

Ответ 4

В моем приложении я установил

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

Кроме того, я установил

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

Теперь ширина столбца может быть изменена, и столбцы могут быть переупорядочены пользователем. Это работает очень хорошо для меня.

Возможно, это сработает для вас.

Ответ 5

Хорошо, я сделал это вот так:

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

в этом конкретном порядке. Столбцы изменяются (расширены), и пользователь может впоследствии изменить размер столбцов.

Ответ 6

Если я правильно понял вопрос, должен быть более простой способ выполнить то, что вам нужно. Вызов dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

Это должно сделать трюк. Однако есть одна ошибка, так как вы не можете просто вызвать этот метод непосредственно после заполнения элемента управления DataGridView. Вместо этого вам нужно будет добавить EventHandler для события VisibleChanged и вызвать метод там.

Ответ 7

После добавления данных в сетку добавьте следующий код, который отрегулирует столбец в соответствии с длиной данных в каждой ячейке

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

Вот результат

enter image description here

Ответ 8

Резюме вопроса:
Используйте ширину столбца для контента (с помощью другого метода в столбце),
но затем разрешить пользователю устанавливать ширину столбца...

Разработка Miroslav Zadravec answer, для меня то, что работало, сразу же использовало автоматическое вычисление column.Width для установки... column.Width!

foreach (DataGridViewColumn column in dataGridView.Columns)
{
    if (/*It 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

Это проверено на работу, когда DataGridView уже создан, используя трюк вроде this.

Ответ 9

Слегка аккуратный код С# из кода Miroslav Zadravec, предполагающий, что все столбцы должны быть авторизованы

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

Ответ 10

Это автоматически проверяет все столбцы в соответствии с их содержимым, заполняет оставшееся пустое пространство, растягивая указанный столбец и предотвращая поведение "прыжка", устанавливая последний столбец для заполнения любого будущего изменения размера.

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

Ответ 11

Другая версия кода 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 при инициализации формы, и если обе части там, ничего не меняется, потому что, вероятно, autosize вычисляет ширины после datagridview, поэтому ширина по-прежнему по умолчанию в методе Form1(). После завершения этого метода autosize делает свой трюк и сразу после этого (когда отображается форма) мы можем установить ширину на вторую часть кода (здесь в событии Form1Shown). Это работает для меня как шарм.

Ответ 12

Здесь упрощенный код для Мирослава Задравеца в С#:

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;

Ответ 13

Вы пытались настроить свойство FillWeight вашего объекта DataGridViewColumns?

Например:

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

Я думаю, что он должен работать в вашем случае.

Ответ 14

Небольшое улучшение от версии 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;
}

Ответ 15

dataGridView1.AutoResizeColumns();

Ответ 16

Ширины столбцов, установленные в соответствии с его содержимым, я использовал приведенную ниже инструкцию, Он разрешил мою проблему.

Первый шаг:

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

Ответ 17

Если вы привязываете свой источник данных к datatable, например, вам нужно установить свойства после завершения привязки:

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

Ответ 18

  • Спасибо за вышеприведенное решение (Чтобы выполнить итерацию через 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;
    
  • Я не знаю, как это работает только после отображения формы.

Ответ 19

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

Это должно работать, отображается ли dataGridView или нет (т.е. даже если вызывается из конструктора класса).

Тот же метод, но с DataGridViewAutoSizeColumnMode.DisplayedCells, по очевидной причине не работает в указанном выше случае - пока не отображается клетка! По какой-то неочевидной причине AutoResizeColumns также терпит неудачу в этом случае.

Ответ 20

Я должен был сделать это в 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

Ответ 21

Это удивило меня:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);