J'ai un DataGridView. Certaines des cellules reçoivent leurs données à partir d'un port série: je souhaite insérer les données dans la cellule et le mettre à jour.
J'essaie quelque chose comme ça:
SetValueFromSerial (decimal newValue)
{
dataGridView.CurrentCell.Value = newValue;
}
utiliser une ficelle n'aide pas:
dataGridView.CurrentCell.Value = newValue.ToString ();
Dans les deux cas, je ne vois rien dans la grille et la valeur sous-jacente reste inchangée.
J'ai fait Google et chercher ici, mais je n'ai rien trouvé. (J'ai peut-être oublié quelque chose, peut-être quelque chose d'évident, mais je ne suis pas complètement _ paresseux.)
Si la DataGridView
est liée à la donnée, vous ne devez pas modifier directement le contenu de la cellule. Au lieu de cela, vous devez modifier l'objet lié aux données. Vous pouvez accéder à cet objet via la DataBoundItem
de la DataGridViewRow
:
MyObject obj = (MyObject)dataGridView.CurrentRow.DataBoundItem;
obj.MyProperty = newValue;
Notez que l'objet lié doit implémenter INotifyPropertyChanged
pour que la modification soit reflétée dans DataGridView
dataGridView1[1,1].Value="tes";
Si vous ne souhaitez pas modifier l'objet lié aux données pour une raison quelconque (par exemple, vous souhaitez afficher une vue dans votre grille, mais vous ne souhaitez pas qu'elle fasse partie de l'objet source de données), procédez comme suit:
1.Ajouter la colonne manuellement:
DataGridViewColumn c = new DataGridViewColumn();
DataGridViewCell cell = new DataGridViewTextBoxCell();
c.CellTemplate = cell;
c.HeaderText = "added";
c.Name = "added";
c.Visible = true;
dgv.Columns.Insert(0, c);
2.Dans l'événement DataBindingComplete, procédez comme suit:
foreach (DataGridViewRow row in dgv.Rows)
{if (row.Cells[7].Value.ToString()=="1")
row.Cells[0].Value = "number one"; }
(juste un exemple stupide)
mais n'oubliez pas qu'il DOIT être dans DataBindingComplete, sinon la valeur restera vide
J'ai eu le même problème Avec SQL-Dataadapter pour mettre à jour les données et ainsi de suite
ce qui suit fonctionne bien pour moi
mydatgridview.Rows[x].Cells[x].Value="test"
mydatagridview.enabled = false
mydatagridview.enabled = true
J'ai cherché la solution pour insérer une nouvelle ligne et définir les valeurs individuelles des cellules à l'intérieur, comme Excel. J'ai résolu avec le code suivant:
dataGridView1.ReadOnly = false; //Before modifying, it is required.
dataGridView1.Rows.Add(); //Inserting first row if yet there is no row, first row number is '0'
dataGridView1.Rows[0].Cells[0].Value = "Razib, this is 0,0!"; //Setting the leftmost and topmost cell's value (Not the column header row!)
dataGridView1[1, 0].Value = "This is 0,1!"; //Setting the Second cell of the first row!
Remarque:
J'espère que cela pourrait vous aider.
Vous souvenez-vous de actualiser le dataGridView?
datagridview.refresh();
Essayez de cette façon:
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
Besoin d'écrire deux fois ...
Je suis tombé sur le même problème et l'ai résolu comme suit pour VB.NET. C'est le .NET Framework donc vous devriez pouvoir être capable de vous adapter. Je voulais comparer ma solution et maintenant je vois que personne ne semble la résoudre à ma façon.
Faites une déclaration de champ.
Private _currentDataView as DataView
Vous devez donc parcourir en boucle toutes les lignes et rechercher une cellule contenant une valeur qui se trouve à côté de la cellule que je souhaite modifier.
Public Sub SetCellValue(ByVal value As String)
Dim dataView As DataView = _currentDataView
For i As Integer = 0 To dataView.Count - 1
If dataView(i).Row.Item("projID").ToString.Equals("139") Then
dataView(i).Row.Item("Comment") = value
Exit For ' Exit early to save performance
End If
Next
End Sub
Pour que vous puissiez mieux le comprendre… .. Je sais que ColumnName "projID" vaut 139. Je boucle jusqu'à ce que je le trouve, puis je peux modifier la valeur de "ColumnNameofCell" dans mon cas, "Comment". J'utilise ceci pour les commentaires ajoutés au moment de l'exécution.
Si la DataGridView
a été renseignée par DataSource = x
(c’est-à-dire qu’il existe un lien de données), vous devez modifier les données liées , pas les cellules DataGridView elles-mêmes.
Voici un moyen d'obtenir ces données à partir d'une ligne ou d'une colonne connue:
(YourRow.DataBoundItem as DataRowView).Row['YourColumn'] = NewValue;
dans VB, vous pouvez utiliser celui-ci
Dim selectedRow As DataRowView
selectedRow = dg.Rows(dg.CurrentCell.RowIndex).DataBoundItem
selectedRow("MyProp") = "myValue"
dg.NotifyCurrentCellDirty(True)
grâce à saeed serpooshan pour la dernière ligne
Les travaux suivants. Je me trompe peut-être, mais ajouter une valeur String
ne semble pas compatible avec une cellule DataGridView (je n'avais pas expérimenté ni essayé aucun piratage).
DataGridViewName.Rows[0].Cells[0].Value = 1;
J'ai essayé beaucoup de méthodes, et la seule qui a fonctionné était UpdateCellValue:
dataGridView.Rows[rowIndex].Cells[columnIndex].Value = "New Value";
dataGridView.UpdateCellValue(columnIndex, rowIndex);
J'espère avoir aidé. =)
private void btn_Addtoreciept_Click(object sender, EventArgs e)
{
serial_number++;
dataGridView_inventory.Rows[serial_number - 1].Cells[0].Value = serial_number;
dataGridView_inventory.Rows[serial_number - 1].Cells[1].Value =comboBox_Reciept_name.Text;
dataGridView_inventory.Rows[serial_number - 1].Cells[2].Value = numericUpDown_recieptprice.Value;
dataGridView_inventory.Rows[serial_number - 1].Cells[3].Value = numericUpDown_Recieptpieces.Value;
dataGridView_inventory.Rows[serial_number - 1].Cells[4].Value = numericUpDown_recieptprice.Value * numericUpDown_Recieptpieces.Value;
numericUpDown_RecieptTotal.Value = serial_number;
}
la première fois, ça va bien, mais en appuyant une deuxième fois, cela me donne une erreur "Index était hors limites. Doit être non négatif et moins que la taille de la collection . Nom du paramètre: index" sur la cellule une autre ligne apparaît et ensuite cela fonctionne pour la ligne suivante, et continuez ...
Comme @Thomas l'a dit, l'élément que vous souhaitez modifier doit implémenter INotifyPropertyChanged. Mais, la source de données est également importante. Il doit s'agir de BindingList, que vous pouvez créer facilement à partir de List.
Voici mon exemple. La source de données est d’abord DataTable, que je transfère à List puis que je crée BindingList. Ensuite, je crée BindingSource et utilise BindingList en tant que DataSource à partir de BindingSource. Enfin, DataSource de DataGridView utilise ce BindingSource.
sp_Select_PersonTableAdapter adapter = new sp_Select_PersonTableAdapter();
DataTable tbl = new DataTable();
tbl.Merge(adapter.GetData());
List<Person> list = tbl.AsEnumerable().Select(x => new Person
{
Id = (Int32) (x["Id"]),
Ime = (string) (x["Name"] ?? ""),
Priimek = (string) (x["LastName"] ?? "")
}).ToList();
BindingList<Person> bindingList = new BindingList<Person>(list);
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = bindingList;
dgvPerson.DataSource = bindingSource;
Ce qui est également très important: le créateur de membres de chaque classe doit appeler OnPropertyChanged (). Sans cela, ça ne marchera pas. Donc, ma classe ressemble à ceci:
public class Person : INotifyPropertyChanged
{
private int _id;
private string _name;
private string _lastName;
public int Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
OnPropertyChanged();
}
}
}
public string Name
{
get { return _name; }
set
{
if (value != _name)
{
_name = value;
OnPropertyChanged();
}
}
}
public string LastName
{
get { return _lastName; }
set
{
if (value != _lastName)
{
_lastName= value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Plus d'informations sur ce sujet: http://msdn.Microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx