J'ai un DataTable qui est rempli à partir d'un fichier CSV puis, en utilisant un DataGridView, les données sont éditées en mémoire. Autant que je comprenne l'édition programmatique des données devrait être faite sur le DataTable où l'édition d'utilisateur est faite via. le DataGridView.L'ajout de colonnes à un DataTable lié à un DataGridView ne met pas à jour la vue
Toutefois, lorsque j'ajoute des colonnes par programme au DataTable, il n'est pas reflété automatiquement dans le DataGridView et je suppose que l'inverse est également vrai.
Comment gardez-vous les deux concurrents? Je pensais que l'idée de liaison de données était que c'était automatique ...
Voici le code de configuration pertinente - WorksheetGridView
sous-classes DataGridView
// Can access data directly
public DataTable data = new DataTable();
public WorksheetGridView()
{
InitializeComponent();
// Allow copying from table to clipboard
this.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
// TODO: how to allow both row and column selects?
//this.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
// Load up a blank DataTable to hold user inputted data
int i;
const int numBlankRows = Config.Application.DefaultNumRows;
const int numBlankCols = Config.Application.DefaultNumCols;
// TODO: Figure out how to include this as a config variable
DBNull dfltCellContent = DBNull.Value;
DataRow tmpRow;
// Add columns - i used for naming
for (i = 0; i < numBlankCols; i++)
{
this.AddColumn(i);
}
// Add rows
for (i = 0; i < numBlankRows; i++)
{
tmpRow = this.data.NewRow();
// Fill cells with something (i.e. blank cells)
foreach (DataColumn col in this.data.Columns)
{
tmpRow[col.ColumnName] = DBNull.Value;
}
this.data.Rows.Add(tmpRow);
}
// Link data to the view
this.DataSource = this.data;
}
private void AddColumn(int colIndex)
{
// Adds a column to the data array
DataColumn tmpCol;
tmpCol = new DataColumn();
tmpCol.DataType = Type.GetType(Config.Application.DataType);
tmpCol.ColumnName = "C" + colIndex.ToString();
tmpCol.ReadOnly = false;
tmpCol.Unique = false;
tmpCol.AllowDBNull = true;
this.data.Columns.Add(tmpCol);
}
Le bit qui ne fonctionne pas est plus tard quand je l'appelle pour AddColumn
instance dans ce code pour gérer coller des données délimitées par des tabulations,
public void PasteToCells(string mode)
{
// TODO: Write paste code
int i;
if (Clipboard.ContainsText())
{
string clipBoardContent = Clipboard.GetText();
using (CsvReader pastedCsvReader = new CsvReader(
new StringReader(clipBoardContent), false, '\t'))
{
// TODO: If more rows/cols than in data table then expand accordingly
int numPastedCols = pastedCsvReader.FieldCount;
int currRowIndex, currColumnIndex;
GetSelectedInsertPoint(out currRowIndex, out currColumnIndex);
// Make space for columns if needed
if (mode == "insertcols")
{
int baseIndex = this.data.Columns.Count;
for (i = 0; i < numPastedCols; i++)
{
//this.Columns.Add
// TODO: Doesn't work yet - do you edit the DataGridView and reflect to DataTable or vise-versa?
this.AddColumn(baseIndex + i);
}
}
while (pastedCsvReader.ReadNextRecord())
{
// Make space for rows (row by row) if needed
if (mode == "insertrows")
{
this.data.NewRow();
// TODO: Add a row
}
// Populate the cells with valid pasted text
for (i = 0; i < numPastedCols; i++)
{
this.data.Rows[currRowIndex][currColumnIndex + i] = ConvertCellContent(pastedCsvReader[i]);
}
currRowIndex = currRowIndex + 1;
}
}
}
else
{
// TODO: Do nothing?
Console.WriteLine("No text on clipboard");
}
}
J'ai essayé l'exemple donné ci-dessous et cela fonctionne. Toutefois, lorsque j'essaie de le faire, la barre de défilement horizontale se développe et se contracte brièvement, mais la table du sous-groupe DataGridView
n'est pas mise à jour. La colonne est cependant dans le DataTable
si - par exemple je ne peux pas ajouter une colonne du même nom, le nombre de colonnes reflète aussi les colonnes supplémentaires. Y at-il peut-être une option concepteur qui pourrait restreindre la mise à jour de la DataGridView
?
L'ajout de lignes fonctionne également.
RESOLU:
Le AutoGeneratedColumns
a été mis à false
dans le code de concepteur en dépit d'être true
dans les propriétés de dialogue (et définir explicitement dans le code). Les colonnes initiales ont été générées par programme et ne devraient donc pas être apparues, mais cela n'a pas été pris en compte puisque le code du concepteur a également continué à générer des colonnes «conçues dans» qui étaient initialement utilisées pour le débogage. Moralité: Vérifiez le code généré automatiquement!
En plus de cela, voir this post et this post
En particulier, vérifiez la Valeur AutoGenerateColumns dans le code du concepteur. Réponse sélectionnée puisque l'exemple a beaucoup aidé au débogage! – Brendan