Bagaimana Anda secara otomatis mengubah ukuran kolom dalam kontrol DataGridView DAN mengizinkan pengguna untuk mengubah ukuran kolom pada kisi yang sama?

109

Saya mengisi kontrol DataGridView pada Formulir Windows (C # 2.0 bukan WPF).

Tujuan saya adalah untuk menampilkan grid yang dengan rapi mengisi semua lebar yang tersedia dengan sel - yaitu tidak ada area yang tidak digunakan (abu-abu tua) di sisi kanan dan ukuran setiap kolom secara tepat sesuai dengan data yang dikandungnya, tetapi juga memungkinkan pengguna untuk mengubah ukuran kolom mana pun sesuai dengan keinginan mereka.

Saya mencoba untuk mencapai ini dengan mengatur AutoSizeMode setiap kolom menjadi DataGridViewAutoSizeColumnMode.AllCells kecuali untuk salah satu kolom yang saya atur ke DataGridViewAutoSizeColumnMode.Fill untuk memastikan seluruh area grid diisi dengan rapi dengan data. (Saya tidak keberatan bahwa ketika pengguna mencoba mengubah ukuran kolom ini, ia akan kembali ke ukuran yang memastikan ruang horizontal selalu digunakan.)

Namun, seperti yang saya sebutkan, setelah dimuat saya ingin mengizinkan pengguna untuk mengubah ukuran kolom agar sesuai dengan persyaratan mereka sendiri - dalam mengatur nilai AutoSizeMode ini untuk setiap kolom, pengguna tampaknya kemudian tidak dapat mengubah ukuran kolom tersebut.

Saya sudah mencoba untuk tidak mengatur AutoSizeMode dari semua kolom yang memungkinkan pengubahan ukuran TAPI tidak mengatur ukuran awal sesuai dengan data yang dikandung sel. Hasil yang sama terjadi saat mengubah AutoSizeMode grid kembali ke "Not Set" setelah memuat data.

Apakah ada pengaturan yang saya lewatkan di sini yang memungkinkan pengaturan otomatis lebar kolom default DAN mengubah ukuran pengguna atau adakah teknik lain yang harus saya gunakan saat mengisi kontrol DataGridView?

Stuart Helwig
sumber
jangan setel ke "Not Set" setel ke "None" sehingga pengubahan ukuran tidak akan dikembalikan. Kembali - diuji untuk c #, .net2.0
bh_earth0

Jawaban:

132

Trik ini berhasil untuk saya:

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

Apa yang terjadi di sini adalah Anda menyetel ukuran otomatis ke mode apa pun yang Anda butuhkan, lalu kolom demi kolom Anda menyimpan lebar yang didapat dari penghitungan ukuran otomatis, menghapus ukuran otomatis, dan menyetel lebar ke nilai yang Anda simpan sebelumnya.

Miroslav Zadravec
sumber
1
Saya meletakkan kode serupa dalam rutinitas bernama AutoResizeColumnWidthsYetAllowUserResizing. Ini dipanggil setelah grid diisi pada awalnya dan juga setelah pengguna mengedit data (yaitu, dari event CellEndEdit grid).
DeveloperDan
5
Ini adalah kode yang bagus. Harus diletakkan di acara 'DataGridView1_DataSourceChanged'.
pengguna890332
1
Bagi saya, melakukan hal itu grd.Columns(i).Width = grd.Columns(i).Widthakan berhasil. Lihat disini .
Antonio
2
untuk c # serupa tetapi dengan tanda kurung siku dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
barlop
Ini mungkin datang sangat terlambat, tetapi setiap kesempatan atau cara, kami dapat mengubah ukuran berdasarkan konten baris tertentu? Katakanlah, berdasarkan konten sel di Baris Pertama, terlepas dari lebar sel di baris lain?
Murtuza Husain
45

Mungkin Anda bisa menelepon

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

Setelah menyetel sumber data. Ini akan mengatur lebar dan memungkinkan pengubahan ukuran.

Lebih lanjut tentang Metode MSDN DataGridView.AutoResizeColumns (DataGridViewAutoSizeColumnsMode) .

Umair
sumber
2
Saya tidak yakin mengapa jawaban ini tidak mendapat perhatian lebih. Jauh lebih bersih. Meskipun jika Anda ingin mencocokkan lebar konten sel DataGridViewAutoSizeColumnsMode.AllCells bekerja sedikit lebih baik.
iwalkbarefoot
31
menggunakan solusi ini saya mendapatkan kesalahan berikutnya: "Parameter autoSizeColumnMode tidak valid untuk operasi ini. Tidak dapat NotSet, None atau Fill tetapi perlu menunjukkan kriteria ukuran." . Saya akhirnya menggunakan dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill ini;
itsho
6
Menggunakan DataGridViewAutoSizeColumnMode.Fill tidak berfungsi karena mengabaikan konten sel saat mengukur kolom.
Stuart Helwig
Saya telah menggunakan metode ini dengan DataGridViewAutoSizeColumnsMode.DisplayedCells. Selain itu, di Desainer Formulir, AutoSizeColumnsMode diatur ke Tidak Ada. Saya perlu menjalankan panggilan metode ini di event handler DataBindingComplete dari DataGridView, untuk memastikannya selalu (ulang) ukurannya dengan benar.
Daan
7
Saya tidak mengerti semua upvote ... Ini tidak berfungsi sama sekali, dokumentasi MSDN jelas, melakukan ini mengarah ke ArgumentException jika autoSizeColumnsMode memiliki nilai None atau Fill.
Larry
31

Versi AC # dari kode Miroslav Zadravec

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

Diposting sebagai Wiki Komunitas agar tidak merusak reputasi orang lain

Tom Kidd
sumber
15

Dalam aplikasi saya, saya telah mengatur

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

Juga, saya telah mengatur

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

Sekarang lebar kolom dapat diubah dan kolom dapat diatur ulang oleh pengguna. Itu bekerja dengan cukup baik untuk saya.

Mungkin itu akan berhasil untuk Anda.

Jehof
sumber
Menyetel AutoSizeColumnsMode kisi ke "Isi" tampaknya menyetel semua kolom ke lebar yang sama. Ya, kolom kemudian diubah ukurannya tetapi semua lebar awal salah. Saya mungkin perlu mengatur lebar kolom dalam kode "secara manual".
Stuart Helwig
DV- grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumn-> s <- Mode.Fill; (Anda melewatkan s, itu ColumsMode di sisi kiri dan sisi kanan, sehingga baris Anda tidak dapat dikompilasi) Kode untuk mendapatkan datagridview ke ukuran otomatis sangat mengganggu seperti itu, jadi setidaknya periksa jawaban Anda terlebih dahulu . Ini baris pertama yang Anda tulis dan salah.
barlop
@barlop terima kasih atas balasan Anda. Anda memiliki hak istimewa untuk mengedit pertanyaan dan jawaban. Jika Anda melihat kesalahan dalam kode saya, silakan edit.
Jehof
12

Setelah menambahkan data ke grid tambahkan kode berikut yang akan menyesuaikan kolom sesuai dengan panjang data di setiap sel

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

Ini Hasilnya

masukkan deskripsi gambar di sini

Sarath Avanavu
sumber
9

Nah, saya melakukan ini seperti ini:

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

dalam urutan tertentu itu. Kolom diubah ukurannya (diperpanjang) DAN pengguna dapat mengubah ukuran kolom sesudahnya.

mpss
sumber
6

Jika saya memahami pertanyaannya dengan benar, seharusnya ada cara yang lebih mudah untuk mencapai apa yang Anda butuhkan. Panggilan dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

Itu seharusnya berhasil. Namun, ada satu kendala karena Anda tidak bisa begitu saja memanggil metode ini secara langsung setelah mengisi kontrol DataGridView Anda. Sebagai gantinya Anda harus menambahkan EventHandler untuk kejadian VisibleChanged dan memanggil metode di sana.

Gorgsenegger
sumber
1
Itu akan mengubah ukuran kolom sesuai dengan konten, tetapi tidak akan memastikan semua ruang grid yang tersedia digunakan. Yakni tidak "mengisi" sisa ruang jika ada.
Stuart Helwig
5

Dua baris kode sederhana berfungsi untuk saya.

dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
Rashmin Javiya
sumber
4

Lanjutkan pertanyaan:
Minta lebar kolom menyesuaikan dengan konten (dengan metode berbeda di seluruh kolom),
tetapi kemudian izinkan pengguna untuk mengatur lebar kolom ...

Berkembang dari jawaban Miroslav Zadravec , bagi saya yang berhasil adalah langsung menggunakan auto computed column.Widthto set ... 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

Ini diuji untuk bekerja ketika DataGridViewsudah dibuat, menggunakan trik seperti ini .

Antonio
sumber
Saya lebih suka menggunakan foreach seperti yang dilakukan kode Anda. Itu membuatnya lebih mudah dibaca ketika Anda tidak memiliki matematika di bagian atas loop. Saya melakukannya dengan cara itu, dan "column.Width = column.Width;" menarik.
Greg Barth
4

Ini membuat keajaiban bagi saya:

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
Vaishali
sumber
1
Solusi sederhana!
Mark Kram
1
Bekerja untuk saya hanya jika disetel ke Tidak ada sesudahnya, yaitudataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
Lakukan-baru
3

Ini otomatis mengisikan semua kolom sesuai dengan isinya, mengisi ruang kosong yang tersisa dengan merentangkan kolom tertentu dan mencegah perilaku 'melompat' dengan menyetel kolom terakhir untuk diisi untuk pengubahan ukuran di masa mendatang.

// 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;
wnutt
sumber
Saya tahu itu jawaban lama, tapi saya bekerja dengan baik, bahkan ketika jumlah kolom tidak diketahui sebelumnya.
Nilo Paim
2

Kode C # yang sedikit lebih rapi dari kode Miroslav Zadravec dengan asumsi semua kolom akan diubah ukurannya secara otomatis

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;
}
rampok
sumber
2

Versi lain dari kode Miroslav Zadravec, tetapi sedikit lebih otomatis dan universal:

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

Bagian kedua saya letakkan di acara terpisah, karena saya mengisi datagridvewinisialisasi formulir dan jika kedua bagian tersebut ada, tidak ada yang berubah, karena kemungkinan autosize menghitung lebar setelah datagridviewditampilkan, jadi lebar masih default dalam Form1()metode. Setelah menyelesaikan metode ini, autosize melakukan triknya dan segera setelah itu (ketika bentuk ditampilkan) kita dapat mengatur lebar dengan bagian kedua dari kode (di sini dalam Form1Shownacara). Ini bekerja untuk saya seperti pesona.

LQd
sumber
2

Berikut kode yang disederhanakan untuk jawaban Miroslav Zadravec di 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;
Cassio Accioly
sumber
1

Apakah Anda mencoba menyiapkan FillWeightproperti milik AndaDataGridViewColumns objek ?

Sebagai contoh:

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

Saya pikir itu harus bekerja dalam kasus Anda.

Aleksei Rubanovskii
sumber
1

Sedikit perbaikan dari versi 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;
}
Initrof
sumber
1

dataGridView1.AutoResizeColumns ();

Nick Andriopoulos
sumber
1

Lebar kolom diatur agar sesuai dengan isinya Saya telah menggunakan pernyataan di bawah ini, Ini menyelesaikan masalah saya.

Langkah pertama :

RadGridViewName.AutoSize = true;

Tahap kedua :

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

Langkah Ketiga:

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; 
}
Priyanka
sumber
1
foreach (DataGridViewColumn c in dataGridView.Columns)
    c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);

Ini harus bekerja apakah dataGridViewtelah ditampilkan atau tidak (yaitu bahkan jika dipanggil dari konstruktor kelas).

Metode yang sama, tetapi dengan DataGridViewAutoSizeColumnMode.DisplayedCells, gagal dalam kasus di atas karena alasan yang jelas - belum ada sel yang ditampilkan! Untuk beberapa alasan yang tidak jelas, AutoResizeColumnsjuga gagal dalam kasus ini.

Malam yang Tidak Bisa Dihancurkan
sumber
0

Misalnya, jika Anda mengikat sumber data ke datatable, Anda perlu menyetel properti setelah binding selesai:

        private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            dgv.AutoResizeColumns();
            dgv.AllowUserToResizeColumns = true;
        }
ehh
sumber
0
  • Terima kasih untuk solusi di atas (Untuk mengulangi DataGridView.Columns, ubah AutoSizeModeke yang valid, kumpulkan nilai lebar dan setel kembali setelah diubah AutoSizeModekeDataGridViewAutoSizeColumnMode.None ).
  • Saya berjuang dengan itu, dan perhatikan itu tidak akan berfungsi setiap kali dipanggil dari konstruktor kelas atau baris apa pun sebelumnya Form.Show()atau Form.ShowDialog(). Jadi saya meletakkan potongan kode ini di Form.Shownacara dan ini berfungsi untuk saya.
  • Kode saya yang diubah, terlepas dari apa pun yang DataGridView.AutoSizeColumnsModeditetapkan sebelumnya, saya gunakan DataGridViewColumn.GetPreferredWidth()alih-alih mengubah DataGridViewColumn.AutoSizeModedan mengatur nilai lebar dengan segera, lalu ubah DataGridView.AutoSizeColumnsModesekali:

    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;
    }
  • Pastikan untuk mengatur

            dataGridView.AllowUserToResizeColumns = true;
  • Saya tidak tahu kenapa ini hanya berfungsi setelah formulir ditampilkan.

pengguna1779049
sumber
0

Saya harus melakukan ini di VB dan lebih suka membaginya dengan metode yang saya tempatkan di Modul. Anda dapat menambahkan kolom Isi sebagai parameter ByRef lainnya jika diinginkan.

''' <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
Greg Barth
sumber
0

Anda bisa melakukan sesuatu seperti ini:

   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;

Semua kolom akan beradaptasi dengan konten kecuali yang terakhir akan mengisi grid.

usr4217
sumber
0

Dengan $ array menjadi konten PSCustomObject, ini berfungsi:

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