Как автоматически изменить размер столбцов в элементе управления DataGridView и разрешить пользователю изменять размер столбцов в той же сетке?
я заполняю элемент управления DataGridView в форме Windows (C# 2.0 не WPF).
моя цель-отобразить сетку, которая аккуратно заполняет всю доступную ширину ячейками-т. е. нет неиспользуемых (темно-серых) областей справа и размеров каждого столбца соответственно в соответствии с содержащимися в нем данными,но также позволяет пользователю изменять любому из столбцов по своему вкусу.
Я пытаюсь достичь этого, установив AutoSizeMode каждого столбца, чтобы быть DataGridViewAutoSizeColumnMode.AllCells за исключением одного из столбцов, которые я установил в DataGridViewAutoSizeColumnMode.Заполните для того, чтобы вся область сетки была аккуратно заполнена данными. (Я не возражаю, что когда пользователь пытается изменить размер этого столбца, он возвращается к размеру, который гарантирует, что горизонтальное пространство всегда используется.)
однако, как я уже упоминал, после загрузки я хотел бы позволить пользователю изменять размер столбцов в соответствии с их собственными требования-при установке этих значений AutoSizeMode для каждого столбца кажется, что пользователь не может затем изменить размер этих столбцов.
Я попытался не устанавливать AutoSizeMode всех столбцов, который позволяет изменять размер, но не устанавливает начальный размер в соответствии с данными, содержащимися в ячейках. Тот же результат возникает при изменении AutoSizeMode сетки обратно на "не установлен" после загрузки данных.
есть ли настройка, которую я здесь не хватает, которая позволяет автоматически устанавливать ширина столбцов по умолчанию и размер пользователя или есть другой метод, который я должен использовать при заполнении элемента управления DataGridView?
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;вот и результат
Если я правильно понял вопрос, должен быть более простой способ выполнить то, что вам нужно. Вызов
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);
небольшое улучшение от версии 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; }
ширина столбца устанавливается в соответствии с его содержанием я использовал следующий оператор, Это решило мою проблему.
Первый Этап :
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