Как сказал @Thomas, элемент, который вы хотите изменить, должен реализовывать INotifyPropertyChanged. Но источник данных также важен. Это должен быть BindingList, который вы можете легко создать из List.
Вот мой пример - источником данных является сначала DataTable, который я передаю в List, а затем создаю BindingList. Затем я создаю BindingSource и использую BindingList в качестве источника данных из BindingSource. Наконец, DataSource из DataGridView использует этот 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;
Что также очень важно: каждый член класса должен устанавливать 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));
}
}
Еще по этой теме: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx