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?
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.
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) .
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
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.
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.
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
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.
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 .
Cela a fait des merveilles pour moi:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
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;
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;
}
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;
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.
dataGridView1.AutoResizeColumns ();
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;
}
Un simple deux lignes de code fonctionne pour moi.
dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
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;
}
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.
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
). 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é.
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
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.
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.
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;
}