Reputation: 34463
I have a DataGridView bound to a list. The values show fine, when I click on a value, it starts editing, however when I press Enter, the change is ignored, no data are ever changed. When I place a breakpoint in the Value setter, I can see it is executed after the edit, but no changed data are ever shown. My binding code looks like this:
namespace DataGridViewList
{
public partial class Form1 : Form
{
public struct LocationEdit
{
public string Key { get; set; }
private string _value;
public string Value { get { return _value; } set { _value = value; } }
};
public Form1()
{
InitializeComponent();
BindingList<LocationEdit> list = new BindingList<LocationEdit>();
list.Add(new LocationEdit { Key = "0", Value = "Home" });
list.Add(new LocationEdit { Key = "1", Value = "Work" });
dataGridView1.DataSource = list;
}
}
}
The project is a basic Windows Forms project, with a DataGrid created in a designer, with columns called Key and Value and set DataPropertyName to Key / Value respectively. No values are set to Read Only.
Is there some step I am missing? Do I need to implement INotifyPropertyChanged
, or something else?
Upvotes: 4
Views: 7646
Reputation: 63387
The problem is your are using a struct
as the BindingList item type. The solution is you should change struct
to class
and it works GREAT. However if you want to keep using struct
, I have an idea to make it works, of course it requires more code than simply changing struct
to class
. The whole idea is every time a cell has its value changed, the underlying item (which is a struct) should be assigned to a totally new struct item. That's the only way you can use to change the underlying value, otherwise the cell value after committing change won't be changed. I've found that the event CellParsing
is the one suitable for this case to add custom code, and here is my code:
namespace DataGridViewList
{
public partial class Form1 : Form
{
public struct LocationEdit
{
public string Key { get; set; }
private string _value;
public string Value { get { return _value; } set { _value = value; } }
};
public Form1()
{
InitializeComponent();
BindingList<LocationEdit> list = new BindingList<LocationEdit>();
list.Add(new LocationEdit { Key = "0", Value = "Home" });
list.Add(new LocationEdit { Key = "1", Value = "Work" });
dataGridView1.DataSource = list;
}
//CellParsing event handler for dataGridView1
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e){
LocationEdit current = ((BindingList<LocationEdit>)dataGridView1.DataSource)[e.RowIndex];
string key = current.Key;
string value = current.Value;
string cellValue = e.Value.ToString()
if (e.ColumnIndex == 0) key = cellValue;
else value = cellValue;
((BindingList<LocationEdit>)dataGridView1.DataSource)[e.RowIndex] = new LocationEdit {Key = key, Value = value};
}
}
}
I don't think it's a good idea to keep using struct
that way, class
would be better.
Upvotes: 4