mvvm - WPF DataGrid with DataGrid in RowDetailsTemplate -
my previous post detecting property changes in vm wasn't in depth enough, i'm posting this
i have grid of jobs. each job can have 1 or more employees.
the datagrid's rowdetailstemplate contains grid show employees. parent grid bound list of jobs. inner grid bound list of employees on job model.
the job model:
public class job : _base { private string _jobname = string.empty; public string jobname { { return _jobname; } set { if (_jobname != value) { _jobname = value; raisepropertychanged("jobname"); } } } private string _jobnumber = string.empty; public string jobnumber { { return _jobnumber; } set { if (_jobnumber != value) { _jobnumber = value; raisepropertychanged("jobnumber"); } } } private observablecollection<employee> _employees; public observablecollection<employee> employees { { return _employees; } set { if (_employees != value) { if (_employees != value) { _employees = value; raisepropertychanged("employees"); } } } } private employee _selectedemployee; public employee selectedemployee { { return _selectedemployee; } set { if (_selectedemployee != value) { if (_selectedemployee != value) { _selectedemployee = value; raisepropertychanged("selectedemployee"); } } } } public job() { employees = new observablecollection<employee>(); } }
the employee model
public class employee : _base { private string _employeename = string.empty; public string employeename { { return _employeename; } set { if (_employeename != value) { _employeename = value; raisepropertychanged("employeename"); } } } private bool _ischecked = false; public bool ischecked { { return _ischecked; } set { if (_ischecked != value) { _ischecked = value; raisepropertychanged("ischecked"); } } } }
the xaml
<datagrid itemssource="{binding jobs}" selecteditem="{binding selectedjob}" autogeneratecolumns="false"> <datagrid.columns> <datagridtextcolumn header="job name" binding="{binding jobname}" /> <datagridtextcolumn header="job number" binding="{binding jobnumber}" /> </datagrid.columns> <datagrid.rowdetailstemplate> <datatemplate> <stackpanel orientation="vertical"> <datagrid itemssource="{binding employees}" selecteditem="{binding selectedemployee}" autogeneratecolumns="false"> <datagrid.columns> <datagridcheckboxcolumn binding="{binding ischecked}"/> <datagridtextcolumn binding="{binding employeename}"/> </datagrid.columns> </datagrid> <button margin="5" height="23" width="75" horizontalalignment="left" content="remove"/> </stackpanel> </datatemplate> </datagrid.rowdetailstemplate> </datagrid>
the mainwindowviewmodel
public class mainwindowviewmodel : _base { private observablecollection<job> _jobs; public observablecollection<job> jobs { { return _jobs; } set { if (_jobs != value) { if (_jobs != value) { _jobs = value; raisepropertychanged("jobs"); } } } } private job _selectedjob; public job selectedjob { { return _selectedjob; } set { if (_selectedjob != value) { if (_selectedjob != value) { _selectedjob = value; raisepropertychanged("selectedjob"); } } } } public mainwindowviewmodel() { this.propertychanged += new propertychangedeventhandler(mainwindowviewmodel_propertychanged); } void mainwindowviewmodel_propertychanged(object sender, system.componentmodel.propertychangedeventargs e) { if (e.propertyname.trim().tolower() == "ischecked") { int x = 1; } } }
i have couple of questions:
1) selectedemployee property on job model not fire when click employee in inner grid.
2) mainwindowviewmodel_propertychanged not fire when employee selected.
3) notice button below inner grid. how bind command mainwindowvm?
as have datagrid
inside datagrid's row
, above datagrid somehoweating selectionchange inner datagrid
. solve this, need forcefully update binding source child datagrid. doing capture selectionchanged event inner datagrid , in handler following.private void datagrid_selectionchanged(object sender, selectionchangedeventargs e) { datagrid grid = e.originalsource datagrid; var expression = grid.getbindingexpression(datagrid.selecteditemproperty); expression.updatesource(); }
mainwindowvm not have ischecked property thats why propertychanged property not firing.
to solve need couple of things. problem datagrid cell , rows not inherit datacontext don't come under visual tree. solve have use
bindingproxy
take windows datacontext button in rowdetails of datagrid
define binding proxy class below:
public class mybindingproxy : freezable { public static readonly dependencyproperty bindingdataproperty = dependencyproperty.register("bindingdata", typeof(object), typeof(mybindingproxy), new uipropertymetadata(null)); protected override freezable createinstancecore() { return new mybindingproxy(); } public object bindingdata { { return (object)getvalue(bindingdataproperty); } set { setvalue(bindingdataproperty, value); } } }
now in resources of window (where datagrid is) create instance of proxy , set bindingdata datacontext of window i.e mainwindowviewmodel as:
<window.resources> <local:mybindingproxy x:key="myproxy" bindingdata="{binding}" /> </window.resources>
now set command below on button:
<button margin="5" height="23" width="75" horizontalalignment="left" content="remove" command="{binding bindingdata.mycommand, source={staticresource myproxy}}"/>
Comments
Post a Comment