XXXXX
XXXXX

Reputation: 1096

How to programmatically set cell value in DataGridView?

I have a DataGridView. Some of the cells receive their data from a serial port: I want to shove the data into the cell, and have it update the underlying bound object.

I'm trying something like this:

SetValueFromSerial (decimal newValue)
{
    dataGridView.CurrentCell.Value = newValue;
}

using a string doesn't help:

    dataGridView.CurrentCell.Value = newValue.ToString ();

In both cases, I don't see anything in the grid, and the underlying value is unchanged.

I did Google and search here, but I didn't find anything. (I may have missed something, perhaps something obvious, but I'm not utterly lazy.)

Upvotes: 41

Views: 296888

Answers (15)

Muhammed
Muhammed

Reputation: 1

//to add a new row in DataGrid view   
DataTable dt = dgv.DataSource as DataTable;
dt.Rows.Add(newValue);
dgv.Rows[dgv.Rows.Count-1].Selected = true;

// to update current row
dgv.SelectedRows[dgv.CurrentRow.Index].SetValues(newValue);

Upvotes: 0

gamendola
gamendola

Reputation: 144

I tried a lot of methods, and the only one which worked was UpdateCellValue:

dataGridView.Rows[rowIndex].Cells[columnIndex].Value = "New Value";
dataGridView.UpdateCellValue(columnIndex, rowIndex);

I hope to have helped. =)

Upvotes: 5

Eric Draven
Eric Draven

Reputation: 255

in VB you can use this one

Dim selectedRow As DataRowView
selectedRow = dg.Rows(dg.CurrentCell.RowIndex).DataBoundItem
selectedRow("MyProp") = "myValue"
dg.NotifyCurrentCellDirty(True)

thanks to saeed serpooshan for last row

Upvotes: 1

Matthis Kohli
Matthis Kohli

Reputation: 1995

I came across the same problem and solved it as following for VB.NET. It's the .NET Framework so you should be possible to adapt. Wanted to compare my solution and now I see that nobody seems to solve it my way.

Make a field declaration.

Private _currentDataView as DataView

So looping through all the rows and searching for a cell containing a value that I know is next to the cell I want to change works for me.

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

So that you can better understand it. I know that ColumnName "projID" is 139. I loop until I find it and then I can change the value of "ColumnNameofCell" in my case "Comment". I use this for comments added on runtime.

dataview

Upvotes: 1

Vytautas Jakstys
Vytautas Jakstys

Reputation: 29

Try this way:

dataGridView.CurrentCell.Value = newValue;

dataGridView.EndEdit();

dataGridView.CurrentCell.Value = newValue;

dataGridView.EndEdit();

Need to write two times...

Upvotes: 2

noelicus
noelicus

Reputation: 15055

If the DataGridView has been populated by DataSource = x (i.e. is databound) then you need to change the bound data, not the DataGridView cells themselves.

One way of getting to that data from a known row or column is thus:

(YourRow.DataBoundItem as DataRowView).Row['YourColumn'] = NewValue;

Upvotes: 0

Razib Ali
Razib Ali

Reputation: 300

I searched for the solution how I can insert a new row and How to set the individual values of the cells inside it like Excel. I solved with following code:

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!

Note:

  1. Previously I have designed the columns in design mode.
  2. I have set the row header visibility to false from property of the datagridview.
  3. The last line is important to understand: When yoou directly giving index of datagridview, the first number is cell number, second one is row number! Remember it!

Hope this might help you.

Upvotes: 5

Asif Ali
Asif Ali

Reputation: 1

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

on first time it goes well but pressing 2nd time it gives me error "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index" but when i click on the cell another row appears and then it works for the next row, and carry on ...

Upvotes: 0

Juergen
Juergen

Reputation: 41

I had the same problem with sql-dataadapter to update data and so on

the following is working for me fine

mydatgridview.Rows[x].Cells[x].Value="test"
mydatagridview.enabled = false 
mydatagridview.enabled = true 

Upvotes: 4

FrenkyB
FrenkyB

Reputation: 7197

Just like @Thomas said, the element you want to change must implement INotifyPropertyChanged. But, datasource is also important. It has to be BindingList, which you can create easily from List.

Here is my example - data source is at first DataTable, which I transfer to List and then create BindingList. Then I create BindingSource and use BindingList as DataSource from BindingSource. At last, DataSource from DataGridView uses this 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;

What is also very important: each class's member setter must call OnPropertyChanged(). Without that, it won't work. So, my class looks like this:

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

    }

More on this topic: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

Upvotes: 0

user2301036
user2301036

Reputation: 9

The following works. I may be mistaken but adding a String value doesn't seem compatible to a DataGridView cell (I hadn't experimented or tried any hacks though).

DataGridViewName.Rows[0].Cells[0].Value = 1;

Upvotes: 0

BornToCode
BornToCode

Reputation: 10213

If you don't want to modify the databound object from some reason (for example you want to show some view in your grid, but you don't want it as a part of the datasource object), you might want to do this:

1.Add column manually:

    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.In the DataBindingComplete event do something like this:

foreach (DataGridViewRow row in dgv.Rows)
{if (row.Cells[7].Value.ToString()=="1")
row.Cells[0].Value = "number one"; }

(just a stupid example)

but remember IT HAS to be in the DataBindingComplete, otherwise value will remain blank

Upvotes: 6

arced
arced

Reputation: 487

dataGridView1[1,1].Value="tes";

Upvotes: 40

Thomas Levesque
Thomas Levesque

Reputation: 292355

If the DataGridView is databound, you shouldn't directly modify the content of the cell. Instead, you should modify the databound object. You can access that object through the DataBoundItem of the DataGridViewRow :

MyObject obj = (MyObject)dataGridView.CurrentRow.DataBoundItem;
obj.MyProperty = newValue;

Note that the bound object should implement INotifyPropertyChanged so that the change is reflected in the DataGridView

Upvotes: 44

Graviton
Graviton

Reputation: 83244

Do you remember to refresh the dataGridView?

datagridview.refresh();

Upvotes: 4

Related Questions