C# 如何在 DataGridView 中以编程方式设置单元格值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1516252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically set cell value in DataGridView?
提问by XXXXX
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.
我有一个 DataGridView。一些单元从串行端口接收它们的数据:我想将数据推送到单元中,并让它更新底层绑定对象。
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 utterlylazy.)
我做了谷歌并在这里搜索,但我没有找到任何东西。(我可能错过了一些东西,也许是显而易见的,但我并不是完全懒惰。)
采纳答案by Thomas Levesque
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
:
如果DataGridView
是数据绑定,则不应直接修改单元格的内容。相反,您应该修改数据绑定对象。您可以通过访问该对象DataBoundItem
的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
请注意,绑定对象应该实现,INotifyPropertyChanged
以便更改反映在DataGridView
回答by arced
dataGridView1[1,1].Value="tes";
回答by Juergen
I had the same problem with sql-dataadapter to update data and so on
我在使用 sql-dataadapter 更新数据等方面遇到了同样的问题
the following is working for me fine
以下对我来说很好
mydatgridview.Rows[x].Cells[x].Value="test"
mydatagridview.enabled = false
mydatagridview.enabled = true
回答by BornToCode
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:
1.手动添加列:
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:
2.在 DataBindingComplete 事件中做这样的事情:
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
但请记住它必须在 DataBindingComplete 中,否则值将保持空白
回答by user2301036
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).
以下作品。我可能弄错了,但添加一个String
值似乎与 DataGridView 单元格不兼容(虽然我没有试验或尝试过任何黑客攻击)。
DataGridViewName.Rows[0].Cells[0].Value = 1;
回答by FrenkyB
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.
正如@Thomas 所说,您要更改的元素必须实现 INotifyPropertyChanged。但是,数据源也很重要。它必须是 BindingList,您可以从 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.
这是我的示例 - 数据源首先是 DataTable,我将其传输到 List,然后创建 BindingList。然后我创建 BindingSource 并使用 BindingList 作为来自 BindingSource 的 DataSource。最后,来自 DataGridView 的 DataSource 使用此 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:
还有一点很重要:每个类的成员 setter 都必须调用 OnPropertyChanged()。没有它,它就行不通。所以,我的班级看起来像这样:
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
有关此主题的更多信息:http: //msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
回答by Asif Ali
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 ...
第一次运行良好但按第二次它给我错误“索引超出范围。必须是非负且小于集合的大小。参数名称:索引”但是当我单击单元格时会出现另一行然后它适用于下一行,并继续......
回答by Razib Ali
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:
我搜索了如何插入新行以及如何像 Excel 一样设置其中单元格的各个值的解决方案。我用以下代码解决了:
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:
笔记:
- Previously I have designed the columns in design mode.
- I have set the row header visibility to false from property of the datagridview.
- 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!
- 以前我在设计模式下设计了列。
- 我已从 datagridview 的属性将行标题可见性设置为 false。
- 最后一行需要理解:当你直接给出datagridview的索引时,第一个数字是单元格号,第二个是行号!记住它!
Hope this might help you.
希望这可以帮助你。
回答by noelicus
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.
如果DataGridView
已填充DataSource = x
(即数据绑定),则您需要更改绑定数据,而不是 DataGridView 单元格本身。
One way of getting to that data from a known row or column is thus:
因此,从已知行或列获取该数据的一种方法是:
(YourRow.DataBoundItem as DataRowView).Row['YourColumn'] = NewValue;