wpf - DataGrid custom CanUserAddRows implementation -
i want implement custom add row button datagrid
(it's long story). added button in template, , define attached property, , can button's click. can not add new row in generic way -not specified type-. know can similar thing in viewmodel
, i'm looking in templates , attached properties. here try; idea complete this?
xaml:
<style x:key="{x:type datagrid}" targettype="{x:type datagrid}"> <setter property="template"> <setter.value> <controltemplate targettype="{x:type datagrid}"> <border x:name="border"> <scrollviewer x:name="dg_scrollviewer" focusable="false"> <scrollviewer.template> <controltemplate targettype="{x:type scrollviewer}"> <grid> <grid.columndefinitions> <columndefinition width="auto" /> <columndefinition width="*" /> <columndefinition width="auto" /> </grid.columndefinitions> <grid.rowdefinitions> <rowdefinition height="auto" /> <rowdefinition height="*" /> <rowdefinition height="auto" /> </grid.rowdefinitions> <button focusable="false" command="{x:static datagrid.selectallcommand}" /> <datagridcolumnheaderspresenter x:name="part_columnheaderspresenter" grid.column="1" /> <grid grid.columnspan="2" grid.row="1"> <grid.rowdefinitions> <rowdefinition height="*"/> <rowdefinition height="22" /> </grid.rowdefinitions> <scrollcontentpresenter x:name="part_scrollcontentpresenter" /> <!-- custom button add new row --> <button x:name="part_addrowbutton" content="add"/> </grid> <scrollbar x:name="part_verticalscrollbar"/> <grid grid.column="1" grid.row="2"> <scrollbar x:name="part_horizontalscrollbar"/> </grid> </grid> </controltemplate> </scrollviewer.template> <itemspresenter snapstodevicepixels="{templatebinding snapstodevicepixels}" /> </scrollviewer> </border> </controltemplate> </setter.value> </setter> </style>
c#:
public class datagridhelper { public static readonly dependencyproperty canuseraddrowsproperty = dependencyproperty.registerattached( "canuseraddrows", typeof(bool), typeof(datagridhelper), new frameworkpropertymetadata(default(bool), canuseraddrowschanged)); [attachedpropertybrowsablefortype(typeof(datagrid))] public static bool getcanuseraddrows(dependencyobject obj) { return (bool)obj.getvalue(canuseraddrowsproperty); } [attachedpropertybrowsablefortype(typeof(datagrid))] public static void setcanuseraddrows(dependencyobject obj, bool value) { obj.setvalue(canuseraddrowsproperty, value); } private static void canuseraddrowschanged( dependencyobject d, dependencypropertychangedeventargs e) { var datagrid = d datagrid; if (datagrid == null) return; bool oldvalue = (bool)e.oldvalue, newvalue = (bool)e.newvalue; if (newvalue == oldvalue) return; if (newvalue) { datagrid.loaded += canuseraddrowsdatagridloaded; } else { datagrid.loaded -= canuseraddrowsdatagridloaded; } } private static void canuseraddrowsdatagridloaded(object sender, routedeventargs e) { var datagrid = sender datagrid; if (datagrid == null) return; if (datagrid.style == null) return; var roottemplate = datagrid.template; if (roottemplate == null) return; var scroll = roottemplate.findname("dg_scrollviewer", datagrid) scrollviewer; if (scroll == null) return; var scrolltemplate = scroll.template; if (scrolltemplate == null) return; var button = scrolltemplate.findname("part_addrowbutton", scroll) buttonbase; if (button == null) return; if (getcanuseraddrows(datagrid)) { button.click += addrowclicked; } else { button.click -= addrowclicked; } } private static void addrowclicked(object sender, routedeventargs e) { var button = ((buttonbase)sender); var parent = visualtreehelper.getparent(button); while (!(parent datagrid)) parent = visualtreehelper.getparent(parent); var source = ((datagrid)parent).items.add(...) // what??? } }
well, can see, got access datagrid
after button got clicked; next? how can force datagrid
show newitemplaceholder
?
typically in wpf, bind collections (preferably collections support change notification observablecollection
) of data objects ui controls. rather adding new items ui controls, add items collections in code behind/view model. long collection support change notification, ui controls automatically updated.
so add new row datagrid
, need add new item collection:
datacollection.add(new datatype());
you should able access data bound collection in attachedproperty
using:
var datacollection = (datacollectiontype)datagrid.itemssource;
i believe can use:
datagrid.items.add(new datatype());
although method not recommended.
Comments
Post a Comment