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



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



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



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



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



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



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

1813   23  

23 ответов:

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

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

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

может быть, вы могли бы назвать

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

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

еще на MSDN DataGridView.Метод AutoResizeColumns (DataGridViewAutoSizeColumnsMode).

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

опубликовано как сообщество Вики, чтобы не слоняться от репутации других

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

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

кроме того, я поставил

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

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

может быть, это сработает для вас.

Ну, я сделал это так:

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

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

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

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

вот и результат

enter image description here

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

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

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

развитие от Мирослав Zadravec это!--10-->, для меня то, что работало, сразу же использовало автоматический вычисленный 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

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

немного опрятнее код C# из кода Мирослав Zadravec это при условии, что все столбцы должны быть autosized

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

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

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

другая версия код Мирослав 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 событие). Это работает для меня, как шарм.

вот упрощенный код для ответа Мирослав 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;

Это сделало чудеса для меня:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

вы пытались настроить FillWeight свойства

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

dataGridView1.AutoResizeColumns ();

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

Первый Этап :

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

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

        private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.AutoResizeColumns();
            dgv.AllowUserToResizeColumns = true;
        }
  • Спасибо за решение выше (для итерации через 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;
    
  • Я не знаю, почему это работает только после того, как форма показана.

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

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

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

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

вы могли бы сделать что-то вроде этого:

   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;

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

простой две строки кода работает для меня.

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

Comments

    Ничего не найдено.