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.)
This question is related to
c#
winforms
datagridview
Try this way:
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
dataGridView.CurrentCell.Value = newValue;
dataGridView.EndEdit();
Need to write two times...
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
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
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.
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
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:
Hope this might help you.
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;
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 ...
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. =)
Do you remember to refresh the dataGridView?
datagridview.refresh();
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
dataGridView1[1,1].Value="tes";
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;
Source: Stackoverflow.com