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?

  1. as have datagridinside datagrid's row, above datagrid somehow eating 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();    } 
  2. mainwindowvm not have ischecked property thats why propertychanged property not firing.

  3. 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

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -