web-dev-qa-db-fra.com

Comment redimensionnez-vous automatiquement les colonnes dans un contrôle DataGridView ET autorisez l'utilisateur à redimensionner les colonnes sur cette même grille?

Je renseigne un contrôle DataGridView sur un Windows Form (C # 2.0 et non WPF).

Mon objectif est d’afficher une grille qui remplit parfaitement toutes les largeurs disponibles avec des cellules - c’est-à-dire qu’il n’ya pas de zones inutilisées (gris foncé) dans le coin droit et que chaque colonne est dimensionnée correctement en fonction des données qu’elle contient. mais permet également à l'utilisateur de redimensionner toutes les colonnes à leur convenance.

J'essaie d'y parvenir en définissant le paramètre AutoSizeMode de chaque colonne sur DataGridViewAutoSizeColumnMode.AllCells sauf pour l'une des colonnes que j'ai définie sur DataGridViewAutoSizeColumnMode.Fill afin de garantir la totalité de la grille soigneusement rempli de données. (Cela ne me dérange pas que lorsque l'utilisateur tente de redimensionner cette colonne, elle reprend sa taille qui garantit que l'espace horizontal est toujours utilisé.)

Cependant, comme je l’ai mentionné, une fois chargé, je voudrais permettre à l’utilisateur de redimensionner les colonnes en fonction de leurs propres besoins - lors de la définition de ces valeurs AutoSizeMode pour chaque colonne, il apparaît que l’utilisateur est alors incapable de redimensionner ces colonnes.

J'ai essayé de ne pas définir le mode AutoSizeMode de toutes les colonnes, ce qui autorise le redimensionnement, MAIS il ne définit pas la taille initiale en fonction des données contenues dans les cellules. Le même résultat se produit lors de la modification du mode AutoSizeMode de la grille sur "Non défini" après le chargement des données.

Y at-il un paramètre qui me manque ici qui permet le réglage automatique des largeurs de colonne par défaut ET le redimensionnement utilisateur ou y a-t-il une autre technique que je dois utiliser lors du remplissage du contrôle DataGridView?

98
Stuart Helwig

Cette astuce fonctionne pour moi:

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

Ce qui se passe ici, c’est que vous définissez la taille automatique sur le mode souhaité, puis que vous stockez colonne par colonne la largeur obtenue à partir du calcul de la taille automatique, supprimez la taille automatique et définissez la largeur sur la valeur précédemment stockée.

115
Miroslav Zadravec

Peut-être que vous pourriez appeler

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);

Après avoir défini la source de données. Il va définir la largeur et permettre le redimensionnement.

Plus d'informations sur MSDN DataGridView.AutoResizeColumns, méthode (DataGridViewAutoSizeColumnsMode) .

38
Umair

Une version C # du code de 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;
}

Publié en tant que Wiki communautaire pour ne pas perdre de la réputation des autres

28
Tom Kidd

Dans mon application j'ai mis

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

Aussi, j'ai mis le 

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

La largeur des colonnes peut maintenant être modifiée et les colonnes peuvent être réorganisées par l'utilisateur. Cela fonctionne plutôt bien pour moi.

Peut-être que cela fonctionnera pour vous.

11
Jehof

Eh bien, j'ai fait ça comme ça:

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

dans cet ordre particulier. Les colonnes sont redimensionnées (étendues) ET l'utilisateur peut ensuite redimensionner les colonnes.

8
mpss

Après avoir ajouté les données à la grille, ajoutez le code suivant qui ajustera la colonne en fonction de la longueur des données dans chaque cellule.

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

Voici le résultat

enter image description here

7
Sarath Avanavu

Si j'ai bien compris la question, il devrait exister un moyen plus simple de répondre à vos besoins. Appelez dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);

Cela devrait faire l'affaire. Cependant, il y a un piège car vous ne pouvez pas simplement appeler cette méthode directement après avoir rempli votre contrôle DataGridView. Au lieu de cela, vous devrez ajouter un gestionnaire d'événements pour l'événement VisibleChanged et appeler la méthode qui s'y trouve.

6
Gorgsenegger

Résumé de la question:
Faire en sorte que la largeur de la colonne s'adapte au contenu (avec une méthode différente dans la colonne),
mais permet ensuite à l'utilisateur de définir la largeur de la colonne ...

Développer à partir de Réponse de Miroslav Zadravec , pour moi, ce qui a bien fonctionné a été d'utiliser immédiatement le column.Width calculé automatiquement pour définir ... 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

Ceci est testé pour fonctionner lorsque la DataGridView est déjà créée, en utilisant une astuce telle que this .

4
Antonio

Cela a fait des merveilles pour moi: 

dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
3
Vaishali

Voici un code simplifié pour la réponse de Miroslav Zadravec en 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;
2
Cassio Accioly

Code C # légèrement plus net du code de Miroslav Zadravec en supposant que toutes les colonnes doivent être automatiquement dimensionnées

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
Rob

Cela adapte automatiquement toutes les colonnes en fonction de leur contenu, remplit l'espace vide restant en étirant une colonne spécifiée et empêche le comportement de "saut" en définissant la dernière colonne à remplir pour tout redimensionnement futur.

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

Une autre version du code de Miroslav Zadravec, mais légèrement plus automatisée et universelle:

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

Je mets la deuxième partie dans un événement séparé, car je remplis datagridvew lors de l'initialisation du formulaire et si les deux parties sont présentes, rien ne change, car la taille automatique calcule probablement les largeurs après l'affichage de datagridview; les largeurs restent donc par défaut dans Form1() . Une fois cette méthode terminée, la taille automatique fait son travail et immédiatement après (lorsque le formulaire est affiché), nous pouvons définir les largeurs par la deuxième partie du code (ici, dans l'événement Form1Shown). Cela fonctionne pour moi comme un charme.

2
LQd

dataGridView1.AutoResizeColumns ();

1
Nick Andriopoulos

La largeur de colonne définie pour correspondre à son contenu J'ai utilisé l'instruction ci-dessous, .__, qui a résolu mon problème.

Premier pas : 

RadGridViewName.AutoSize = true;

Deuxième étape :

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

Troisième étape : 

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
Priyanka

Un simple deux lignes de code fonctionne pour moi.

dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
1
Rashmin Javiya

Une petite amélioration par rapport à la version de 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
Initrof

Avez-vous essayé de configurer la propriété FillWeight de votre objet DataGridViewColumns?

Par exemple:

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

Je pense que cela devrait fonctionner dans votre cas.

1
Rubanovsky Alex
  • Merci pour la solution ci-dessus (pour parcourir le DataGridView.Columns, remplacez AutoSizeMode par un valide, collectez la valeur de la largeur et définissez-la après la modification du AutoSizeMode en DataGridViewAutoSizeColumnMode.None). 
  • J'ai eu du mal à l'utiliser et j'ai remarqué que cela ne fonctionnerait pas à chaque appel depuis le constructeur de la classe ou une ligne avant Form.Show() ou Form.ShowDialog(). J'ai donc mis cet extrait de code dans l'événement Form.Shown et cela fonctionne pour moi. 
  • Mon code transformé, sans enregistrer quoi que ce soit DataGridView.AutoSizeColumnsMode défini auparavant, j'utilise DataGridViewColumn.GetPreferredWidth() au lieu de changer DataGridViewColumn.AutoSizeMode et de définir immédiatement la valeur de la largeur, puis de changer DataGridView.AutoSizeColumnsMode une fois: 

    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;
    }
    
  • Assurez-vous de définir 

            dataGridView.AllowUserToResizeColumns = true;
    
  • Je ne sais pas pourquoi cela ne fonctionne que lorsque le formulaire est affiché.

0
user1779049

Je devais le faire dans VB et préférer le scinder en une méthode que je plaçais dans un module. Vous pouvez ajouter la colonne Remplir comme autre paramètre ByRef si vous le souhaitez.

''' <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
Greg Barth
foreach (DataGridViewColumn c in dataGridView.Columns)
    c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);

Cela devrait fonctionner que la variable dataGridView ait été affichée ou non (c'est-à-dire même si elle a été appelée à partir du constructeur de la classe).

La même méthode, mais avec DataGridViewAutoSizeColumnMode.DisplayedCells, échoue dans le cas ci-dessus pour une raison évidente: aucune cellule n'a encore été affichée! Pour une raison non évidente, AutoResizeColumns échoue également dans ce cas.

0

Vous pouvez faire quelque chose comme ça:

   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;

Toutes les colonnes s'adapteront au contenu sauf le dernier qui remplira la grille.

0
usr4217

Si vous liez votre source de données à un datatable par exemple, vous devez définir les propriétés une fois la liaison établie:

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