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
Post a Comment