web-dev-qa-db-fra.com

Comment définir par programme la valeur d'une cellule dans DataGridView?

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.)

35
XXXXX

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

33
Thomas Levesque
dataGridView1[1,1].Value="tes";
28
arced

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

5
BornToCode

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 
4
Juergen

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:

  1. Auparavant, j'avais conçu les colonnes en mode Création.
  2. J'ai défini la visibilité d'en-tête de ligne sur false à partir de la propriété de datagridview.
  3. La dernière ligne est importante à comprendre: Lorsque vous donnez directement l’index de datagridview, le premier numéro correspond au numéro de cellule, le second au numéro de ligne! Souviens toi!

J'espère que cela pourrait vous aider.

4
Razib Ali

Vous souvenez-vous de actualiser le dataGridView?

datagridview.refresh();
4
Graviton

Essayez de cette façon:

dataGridView.CurrentCell.Value = newValue;

dataGridView.EndEdit();

dataGridView.CurrentCell.Value = newValue;

dataGridView.EndEdit();

Besoin d'écrire deux fois ...

3
Vytautas Jakstys

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.

 dataview

1
Matthis Kohli

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;
1
noelicus

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

1
Eric Draven

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;
1
user2301036

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é. =)

0
gamendola
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 ... 

0
Asif Ali

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

0
FrenkyB