c# - BindingError 40 on DataGrid CellEditingTemplate -


i have strange bug datatemplate "persondatatemplate" use celltemplate , ascelleditingtemplate. on celltemplate works fine on celleditingtemplate following error

system.windows.data error: 40 : bindingexpression path error: 'personid' property not found on 'object' ''datarowview' (hashcode=59318978)'. bindingexpression:path=personid; dataitem='datarowview' (hashcode=59318978); target element 'textblock' (name=''); target property 'text' (type 'string') system.windows.data error: 40 : bindingexpression path error: 'personname' property not found on 'object' ''datarowview' (hashcode=59318978)'. bindingexpression:path=personname; dataitem='datarowview' (hashcode=59318978); target element 'textblock' (name=''); target property 'text' (type 'string') 

my template

    <datatemplate x:key="persondatatemplate" datatype="person">         <stackpanel>             <textblock background="lightblue" text="{binding personid}"/>             <textblock background="aliceblue" text="{binding personname}"/>         </stackpanel>     </datatemplate> 

and here rest of code

person.cs

 public class person     {         private int personid;         private string personname;          public int personid         {             { return personid; }             set { personid = value; }         }         public string personname         {             { return personname; }             set { personname = value; }         }     } 

mainwindow.cs

public partial class mainwindow : window {     public mainwindow()     {         initializecomponent();          simpledatagrid.itemssource = loaddatatable().asdataview();     }      /// <summary>     /// here place persondatatemplate celltemplate , celleditingtemplate     /// </summary>     private void simpledatagrid_autogeneratingcolumn(object sender, datagridautogeneratingcolumneventargs e)     {         if (e.propertytype == typeof(person))         {             mydatagridtemplatecolumn col = new mydatagridtemplatecolumn();             col.columnname = e.propertyname;             col.celltemplate = (datatemplate)findresource("persondatatemplate");             col.celleditingtemplate = (datatemplate)findresource("persondatatemplate");             e.column = col;             e.column.header = e.propertyname;         }     }      /// <summary>     /// here create , fill datatable     /// </summary>     private datatable loaddatatable()     {         var _simpledatatable = new datatable();          var person = new datacolumn("person") { datatype = typeof(person) };         _simpledatatable.columns.add(person);          var dr1 = _simpledatatable.newrow();         dr1[0] = new person { personid = 1, personname = "tony" };         _simpledatatable.rows.add(dr1);          var dr2 = _simpledatatable.newrow();         dr2[0] = new person { personid = 2, personname = "mal" };         _simpledatatable.rows.add(dr2);          _simpledatatable.acceptchanges();          return _simpledatatable;     }      private void simpledatagrid_beginningedit(object sender, datagridbeginningediteventargs e)     {         // check values     } }  public class mydatagridtemplatecolumn : datagridtemplatecolumn {     public string columnname { get; set; }      protected override system.windows.frameworkelement generateelement(datagridcell cell, object dataitem)     {         // datagridtemplatecolumn uses contentpresenter datatemplate.         contentpresenter cp = (contentpresenter)base.generateelement(cell, dataitem);         // reset binding specific column. default binding datarowview.         bindingoperations.setbinding(cp, contentpresenter.contentproperty, new binding(this.columnname));         return cp;     } } 

mainwindow.xaml

<window x:class="howbinddatatabletodatagrid.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         title="mainwindow" height="350" width="525">     <window.resources>         <!-- each class 1 datatemplate-->         <datatemplate x:key="persondatatemplate" datatype="person">             <stackpanel>                 <textblock background="lightblue" text="{binding personid}"/>                 <textblock background="aliceblue" text="{binding personname}"/>             </stackpanel>         </datatemplate>     </window.resources>     <grid>         <datagrid name="simpledatagrid" autogeneratingcolumn="simpledatagrid_autogeneratingcolumn" beginningedit="simpledatagrid_beginningedit" />     </grid> </window> 

special information's

  • my itemssource datatable
  • my mydatagridtemplatecolumn based on this answer (i tested other solution no luck)
  • i tested separate datatemplate celleditingtemplate no luck

you should override generateeditingelement too, set content of generated element did on generateelement method :

public class mydatagridtemplatecolumn : datagridtemplatecolumn {     public string columnname { get; set; }      protected override system.windows.frameworkelement generateelement(datagridcell cell, object dataitem)     {         // datagridtemplatecolumn uses contentpresenter datatemplate.         contentpresenter cp = (contentpresenter)base.generateelement(cell, dataitem);          // reset binding specific column. default binding datarowview.         bindingoperations.setbinding(cp, contentpresenter.contentproperty, new binding(this.columnname));         return cp;     }      protected override frameworkelement generateeditingelement(datagridcell cell, object dataitem)     {         // datagridtemplatecolumn uses contentpresenter datatemplate.         contentpresenter cp = (contentpresenter)base.generateeditingelement(cell, dataitem);          // reset binding specific column. default binding datarowview.         bindingoperations.setbinding(cp, contentpresenter.contentproperty, new binding(this.columnname));         return cp;     }  } 

Comments