c# - WPF DataGrid CustomSort for each Column -
i have wpf datagrid bound collectionviewsource encapsulates observablecollection. collectionviewsource has 2 main objectives:
1) group each item specific property of t. i'm using valueconverter in groupdescription grouping behaviour want.
2) sort grid a) group name (as defined above) , b) individual group items. i'm achieving attaching custom icomparer collectionviewsource's 'customsort' property.
this works great part, column header clicked, sorting logic overridden. don't want disable sorting, wondering if possible assign custom sorting order specific column?
to make things bit clearer, suppose user clicks 'columna' - @ moment, sorting logic encapsulated customsorter overridden , datagrid sorted property. rather sorting selected property, i'd instead reverse logic of customsorter.
i created couple of attached properties handle issue. hope comes in handy someone!
first - simple interface directionalised comparer. extends icomparer gives 1 more property (sortdirection). implementation should use determine correct ordering of elements (which otherwise have been lost).
public interface icustomsorter : icomparer { listsortdirection sortdirection { get; set; } } next attached behavior - 2 things: 1) tells grid use custom sort logic (allowcustomsort=true) , b) gives ability set logic @ per-column level.
public class customsortbehaviour { public static readonly dependencyproperty customsorterproperty = dependencyproperty.registerattached("customsorter", typeof(icustomsorter), typeof(customsortbehavior)); public static icustomsorter getcustomsorter(datagridcolumn gridcolumn) { return (icustomsorter)gridcolumn.getvalue(customsorterproperty); } public static void setcustomsorter(datagridcolumn gridcolumn, icustomsorter value) { gridcolumn.setvalue(customsorterproperty, value); } public static readonly dependencyproperty allowcustomsortproperty = dependencyproperty.registerattached("allowcustomsort", typeof(bool), typeof(customsortbehavior), new uipropertymetadata(false, onallowcustomsortchanged)); public static bool getallowcustomsort(datagrid grid) { return (bool)grid.getvalue(allowcustomsortproperty); } public static void setallowcustomsort(datagrid grid, bool value) { grid.setvalue(allowcustomsortproperty, value); } private static void onallowcustomsortchanged(dependencyobject d, dependencypropertychangedeventargs e) { var existing = d datagrid; if (existing == null) return; var oldallow = (bool)e.oldvalue; var newallow = (bool)e.newvalue; if (!oldallow && newallow) { existing.sorting += handlecustomsorting; } else { existing.sorting -= handlecustomsorting; } } private static void handlecustomsorting(object sender, datagridsortingeventargs e) { var datagrid = sender datagrid; if (datagrid == null || !getallowcustomsort(datagrid)) return; var listcolview = datagrid.itemssource listcollectionview; if (listcolview == null) throw new exception("the datagrid's itemssource property must of type, listcollectionview"); // sanity check var sorter = getcustomsorter(e.column); if (sorter == null) return; // guts. e.handled = true; var direction = (e.column.sortdirection != listsortdirection.ascending) ? listsortdirection.ascending : listsortdirection.descending; e.column.sortdirection = sorter.sortdirection = direction; listcolview.customsort = sorter; } } to use it, implement icustomcomparer (with parameterless constructor) , in xaml:
<usercontrol.resources> <converters:mycomparer x:key="mycomparer"/> <!-- add more if need them --> </usercontrol.resources> <datagrid behaviours:customsortbehaviour.allowcustomsort="true" itemssource="{binding mylistcollectionview}"> <datagrid.columns> <datagridtextcolumn header="test" binding="{binding myvalue}" behaviours:customsortbehaviour.customsorter="{staticresource mycomparer}" /> </datagrid.columns> </datagrid>
Comments
Post a Comment