wpf - TextBlock inside DataGridTemplateColumn does not refresh if source changed -
there textblock inside datagridtemplatecolumn, bound viewmodel property (guest.firstnames), displays value correctly. however, when property in viewmodel changed, change not reflect in view. here relevant code
roomslot
public class roomslot : entitybase { [required] public guest guest { get; set; } }
guest
public class guest : entitybase { private string _firstnames; [required(errormessage = "firstnames required")] public string firstnames { { return _firstnames; } set { _firstnames = value; notifyofpropertychange(() => firstnames); } } public list<roomslot> roomslots { get; set; } }
view
<!-- datagrid.datacontext = observablecollection<roomslot> --> <!-- datagridtemplatecolumn.datacontext = roomslot --> <datagridtemplatecolumn header="guest" width="auto" > <datagridtemplatecolumn.celltemplate> <datatemplate> <stackpanel orientation="horizontal" > <textblock text="{binding guest.firstnames, mode=oneway}" fontweight="normal"/> </stackpanel> </datatemplate> </datagridtemplatecolumn.celltemplate> </datagridtemplatecolumn>
viewmodel
public class makereservationviewmodel : conductor<object> { private observablecollection<roomslot> _roomslots; public observablecollection<roomslot> roomslots { { return _roomslots; } set { _roomslots = value; notifyofpropertychange(() => roomslots); } } //changedrecord contains updated guest public void handle(recordchanged<guest> changedrecord) { int = 0; foreach (roomslot slot in roomslots) { if (slot == currentlyeditingslot) { slot.guest = changedrecord.record; notifyofpropertychange(() => roomslots[i].guest.firstnames); notifyofpropertychange(() => roomslots); } i++; } } }
as can see, changing guest.firstnames. guest property of roomslot. guest.firstnames when updated in viewmodel not reflect change in view. why textblock not refresh inspite of raising notifyofpropertychanged (caliburn micro's implementation of inotifypropertychagned)
edit
this in viewmodel
//this receive new roomslots class public void handle(list<roomslot> roomslots) { roomslots = new observablecollection<roomslot>(roomslots); //if apply guest names here given below, appear correctly in view foreach (roomslot slot in roomslots) { slot.guest.firstnames = "sarah anderson"; } }
this above code initializes viewmodel observablecollection property first time. @ point guests names not known, if (for testing) initialize guest.firstnames done above, correctly bindings work , "sarah anderson" appears in datagridtemplatecolumn.
edit 2
works if change definition of roomslot.guest
from this
public class roomslot : entitybase { [required] public guest guest { get; set; } }
to this
public class roomslot : entitybase { private guest _guest; [required] public guest guest { { return _guest; } set { _guest = value; notifyofpropertychange(() => guest); } } }
although not sure why explicitly raising notifyofpropertychange(() => roomslots[i].guest)
doesn't work, above change does