Як ви автоматично змінюєте розмір стовпців у елементі управління DataGridView І дозволяєте користувачеві змінювати розмір стовпців у цій самій сітці?


109

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

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

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

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

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

Чи є тут відсутність у мене налаштування, яке дозволяє автоматично встановлювати ширину стовпців за замовчуванням І змінити розмір користувача чи існує інша техніка, яку я повинен використовувати під час заповнення елемента керування DataGridView?


не встановлюйте його на "Не встановити", встановіть його на "Немає", тому зміна не повернеться Назад - перевірено на c #, .net2.0
bh_earth0

Відповіді:


132

Цей трюк працює для мене:

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
Я ставлю аналогічний код у процедуру з назвою AutoResizeColumnWidthsYetAllowUserResizing. Він викликається після заповнення сітки спочатку, а також після редагування даних користувача (тобто з події CellEndEdit сітки).
DeveloperDan

5
Це чудовий код. Потрібно помістити у події "DataGridView1_DataSourceChanged".
user890332

1
Мені здається, що робити grd.Columns(i).Width = grd.Columns(i).Widthвже трюк. Дивіться тут .
Антоніо

2
для c # подібних, але з квадратними дужками dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
барлоп

Це могло б прийти дуже пізно, але будь-який шанс чи спосіб ми могли змінити розмір на основі вмісту певного рядка? Скажімо, виходячи з вмісту комірок у першій рядці, незалежно від ширини комірок в інших рядах?
Муртуза Хусайн

45

Можливо, ви могли б зателефонувати

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

Після встановлення джерела даних. Він встановить ширину і дозволить змінити розмір.

Детальніше про метод MSDN DataGridView.AutoResizeColumns (DataGridViewAutoSizeColumnsMode) .


2
Я не впевнений, чому ця відповідь не привертає більшої уваги. Значно чистіше. Хоча якщо ви хочете відповідати ширині вмісту комірок, DataGridViewAutoSizeColumnsMode.AllCells працює трохи краще.
iwalkbarefoot

31
використовуючи це рішення, я отримую наступну помилку: "Параметр autoSizeColumnMode недійсний для цієї операції. Він не може бути NotSet, None або Fill, але потрібно вказати критерії розміру." . Я в кінцевому рахунку використовував цей dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
itho

6
Використання DataGridViewAutoSizeColumnMode.Fill не працює, оскільки він ігнорує вміст комірок під час розміщення стовпців.
Стюарт Гельвіг

Я використовував цей метод з DataGridViewAutoSizeColumnsMode.DisplayedCells. Крім того, у конструкторі форм для параметра AutoSizeColumnMode встановлено значення None. Мені потрібно було виконати виклик цього методу в обробнику подій DataBindingComplete DataGridView, щоб переконатися, що він завжди (пере) розмірів належним чином.
Дан

7
Я не розумію всіх оновлень ... Це зовсім не працює, документація MSDN зрозуміла, це призводить до ArgumentException, якщо autoSizeColumnMode має значення None або Fill.
Ларрі

31

AC # версія коду Мирослава Задравець

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 Wiki спільноти, щоб не збиватися з репутації інших


15

У своїй заяві я поставив

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

Крім того, я встановив

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

Тепер ширини стовпців можна змінювати, а користувачі можуть переставляти стовпці. Це працює досить добре для мене.

Можливо, це допоможе тобі.


Якщо встановити параметр AutoSizeColumnsMode в сітці на "Fill", схоже, усі стовпці мають однакові ширини. Так, стовпці можуть бути змінені, але початкові ширини - це неправильно. Можливо, потрібно буде встановити ширину стовпців у коді "вручну".
Стюарт Гельвіг

DV- grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumn-> s <- Mode.Fill; (Ви пропустили s, це ColumsMode з лівої та правої сторони, щоб ваш твій рядок не компілювався) Код для отримання datagridview для автоматичного розміру дуже дратує, як це є, тому принаймні перевірте свою відповідь спочатку . Це перший рядок, який ви написали, і це неправильно.
барлоп

@barlop дякую за вашу відповідь. У вас є прівілег редагувати питання та відповіді. Якщо ви помітили помилку в моєму коді, тоді не соромтесь редагувати.
Jehof

12

Після додавання даних до сітки додайте наступний код, який буде коригувати стовпчик відповідно до довжини даних у кожній комірці

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

Ось результат

введіть тут опис зображення


9

Ну, я зробив це так:

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

в цьому конкретному порядку. Стовпці змінено розмір (розширено) І користувач може змінити розмір стовпців після цього.


6

Якщо я правильно зрозумів питання, то повинен бути простіший спосіб досягти того, що вам потрібно. Дзвінок dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

Це повинно зробити трюк. Однак є одна помилка, оскільки ви не можете просто викликати цей метод безпосередньо після заповнення керування DataGridView. Натомість вам доведеться додати EventHandler для події VisibleChanged і викликати метод там.


1
Це дозволить змінити розмір стовпців відповідно до вмісту, але не забезпечить використання всього доступного простору сітки. Тобто, не «заповнює» залишок місця, якщо він є.
Стюарт Гельвіг

5

Для мене працює простий два рядки коду.

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

4

Резюме питання:
чи адаптувати ширину стовпців до вмісту (різним методом у стовпці),
але потім дозвольте користувачеві встановити ширину стовпця ...

Розвиваючись з відповіді Мирослава Задравець , для мене те, що працювало, було негайно за допомогою автоматичного обчислення 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вже створена, використовуючи трюк , як це .


Я вважаю за краще використовувати foreach, як це робить ваш код. Це робить його більш читабельним, коли у вас немає математики у верхній частині циклу. Я зробив це саме так, і "column.Width = column.Width;" цікаво.
Грег Барт

4

Це робило для мене чудеса:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

1
Просте рішення!
Марк Крам

1
Працював для мене, лише якщо після цього встановлено значення None, тобтоdataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
Do-do-new

3

Це автоматично налаштовує всі стовпці відповідно до їх вмісту, заповнює залишок порожнього простору, розтягуючи вказаний стовпець і запобігаючи поведінці "стрибків", встановлюючи останній стовпчик для заповнення будь-якого майбутнього зміни розміру.

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

Я знаю, що це стара відповідь, але я працюю нікель, навіть коли кількість стовпців заздалегідь не відома.
Ніло Паїм

2

Трохи акуратніший код 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;
}

2

Ще одна версія коду Мирослава Задравець, але трохи більш автоматизована та універсальна:

    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()методі. Закінчивши цей метод, autosize робить свій трюк і відразу після цього (коли буде показана форма) ми можемо встановити ширини другою частиною коду (тут у Form1Shownвипадку). Це працює для мене як шарм.


2

Ось спрощений код для відповіді Мирослава Задравець на 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;

1

Ви намагалися налаштувати FillWeightвласність свогоDataGridViewColumns об'єкта?

Наприклад:

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

Я думаю, це має спрацювати у вашому випадку.


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


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

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

Це повинно працювати, dataGridViewвідображається чи ні (тобто навіть якщо викликається конструктором класу).

Цей же метод, але з цим DataGridViewAutoSizeColumnMode.DisplayedCells, не виходить із зазначеного випадку з очевидних причин - жодна комірка ще не відображалася! З якихось неочевидних причин AutoResizeColumnsтакож у цьому випадку не вдається.


0

Якщо, наприклад, ви прив'язуєте свій джерело даних до таблиці даних, вам потрібно встановити властивості після завершення прив'язки:

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

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;
  • Я не знаю, як це працює лише після того, як буде показана форма.


0

Мені довелося це зробити в VB і вважаю за краще розділити його на метод, який я розмістив у модулі. Ви можете додати стовпчик «Заповнення» як інший параметр 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

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;

Усі стовпці адаптуються до вмісту, крім останнього заповнюватиме сітку.


0

Оскільки масив $ є вмістом PSCustomObject, це працює:

$dataGridView1.DataSource=[collections.arraylist]($array)
$dataGridView1.Columns | Foreach-Object{$_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.