Uit de Microsoft Shared Code release:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| [SRCategory("CatData"), RefreshProperties(RefreshProperties.Repaint), TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), DefaultValue((string) null), SRDescription("DataGridDataSourceDescr")]
public object DataSource
{
get
{
return this.dataSource;
}
set
{
if (((value != null) && !(value is IList)) && !(value is IListSource))
{
throw new Exception(SR.GetString("BadDataSourceForComplexBinding"));
}
if ((this.dataSource == null) || !this.dataSource.Equals(value))
{
if (((value == null) || (value == Convert.DBNull)) && !"".Equals(this.DataMember))
{
this.dataSource = null;
this.DataMember = "";
}
else
{
if (value != null)
{
this.EnforceValidDataMember(value);
}
this.parentRows.Clear();
this.originalState = null;
this.caption.BackButtonActive = this.caption.DownButtonActive = this.caption.BackButtonVisible = false;
this.caption.SetDownButtonDirection(!this.layout.ParentRowsVisible);
this.Set_ListManager(value, this.DataMember, false);
}
}
}
} |
Ofwel als je alleen de data in een object wijzigt en opnieuw het object toewijst (regel 14) zal this.dataSource.Equals(value) true zijn en daardoor ziet het grid simpelweg niet dat er veranderingen zijn. Set_ListManager wordt dus niet aangeroepen en de veranderingen worden dus niet doorgevoerd.
De eenvoudigste workaround is om de datasource aan de ctor van een nieuwe datasource instantie mee te geven. Probleem is namelijk dat DataSet.Equals geen eigen implementatie heeft en dus de implementatie van object erft. Ook List<T> heeft geen eigen Equals implementatie..
Uit de remarks sectie van Object.Equals
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object.
Dat betekend dus zolang het DataSet object zelf niet opnieuw wordt aangemaakt de reference niet wijzigt en daarmee geeft equals dus 'true' terug als de DataSet 'opnieuw' aan het grid wordt gekoppeld.
C#:
1
2
3
4
5
6
7
8
9
10
| List<int> list = new List<int>();
list.Add(1); //
grid.DataSource = list; // <-- eerste toewijzing
list.Add(2); // <-- object (grid.DataSource) heeft geen implementatie van INotifyPropertyChanged dus DataSource weet niet dat de list is gewijzigd, zelfs als List<T> INotifyPropertyChanged zou implementeren.
grid.DataSource = list; // <-- list heeft nog steeds hetzelfde reference en DataGrid refreshed niet.
list = new List<int>(list); //zorgt voor nieuw object referentie
grid.DataSource = list; // <-- deze toewijzing zorgt wel voor een refresh van het datagrid. |
Hoop dat ik duidelijker hen kunnen maken waarom het opnieuw inlezen van de xml dmv ReadXml niet voldoende is voor DataGrid.DataSource om het als een nieuwe data source te zien. Overigens heeft dit verder weinig te maken waarom de columns van de TS veranderen naar het type DataGridTextBoxColumn.
If it isn't broken, fix it until it is..