c# - Count DataGridCells according to a boolean AttachedProperty -
i have e highlighting mechanism changes background of datagridcell according searched pattern.
<setter property="converters:datagridtextsearch.istextmatch"> <setter.value> <multibinding converter="{staticresource searchvalueconverter}"> <binding relativesource="{relativesource self}" path="content.text"/> <binding relativesource="{relativesource self}" path="(converters:datagridtextsearch.searchvalue)" /> <binding relativesource="{relativesource self}" path="column.header" /> </multibinding> </setter.value> </setter> and trigger defined :
<style.triggers> <trigger property="converters:datagridtextsearch.istextmatch" value="true"> <setter property="background" value="lightgray" /> </trigger> </style.triggers> code attachedproperty:
// using dependencyproperty backing store istextmatch. enables animation, styling, binding, etc... public static readonly dependencyproperty istextmatchproperty = dependencyproperty.registerattached("istextmatch", typeof(bool), typeof(datagridtextsearch), new uipropertymetadata(false)); public static bool getistextmatch(dependencyobject obj) { return (bool)obj.getvalue(istextmatchproperty); } public static void setistextmatch(dependencyobject obj, bool value) { obj.setvalue(istextmatchproperty, value); } i count cells have istextmatch true. further more need count rows, there might many cells on 1 row have detect trying go step step.
i tried add attached property in static class count how many "true" set. updated value propertychangedcallback of istextmatchproperty didn't work.
this xaml access property :
converters:datagridtextsearch.cellscount="{binding relativesource={relativesource self}, path=tag, mode=twoway, updatesourcetrigger=propertychanged}" where datagridtextsearch static class in properties resides.
is there other approach? if not, doing wrong here?
basic approach create supervising object, counter, responsible counting of highlighted cells.
public class counter : inotifypropertychanged { hashset<dependencyobject> _hash = new hashset<dependencyobject>(); public void add(dependencyobject obj) { this._hash.add(obj); this.raisepropertychanged("count"); } public void remove(dependencyobject obj) { this._hash.remove(obj); this.raisepropertychanged("count"); } public int count { { return this._hash.count; } } // inotifypropertychanged implementation omitted... } add attached dependency property cellcounter behavior:
// get/set methods omitted public static readonly dependencyproperty counterproperty = dependencyproperty.registerattached( "cellscounter", typeof(counter), typeof(gridbehavior), new frameworkpropertymetadata(gridbehavior.oncellscounterpropertychanged)); private static void oncellscounterpropertychanged(dependencyobject d, dependencypropertychangedeventargs e) { var oldcounter = e.oldvalue counter; if (oldcounter != null) { oldcounter.remove(d); } var newcounter = e.newvalue counter; if (newcounter != null) { var isselected = gridbehavior.getisselected(d); if (isselected) { newcounter.add(d); } } } add logic of incrementing/decrementing of counter istextmatch property:
// get/set methods omitted public static readonly dependencyproperty istextmatchproperty = dependencyproperty.registerattached( "istextmatch", typeof(bool), typeof(gridbehavior), new frameworkpropertymetadata(gridbehavior.onistextmatchpropertychanged)); private static void onistextmatchpropertychanged(dependencyobject d, dependencypropertychangedeventargs e) { var counter = d.getvalue(gridbehavior.cellscounterproperty) counter; if (counter == null) { return; } if ((bool)e.newvalue) { counter.add(d); } else { counter.remove(d); } } then define single counter in resources section of window/control , poll count property wherever want. due inotifypropertychanged nature of counter changes automatically dispatched counter's consumer. (i used listbox instead of datagrid , didn't use view model simplicity doesn't matter):
<window x:class="wpfapplication3.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:view="clr-namespace:wpfapplication3"> <window.resources> <view:counter x:key="counterkey"/> </window.resources> <stackpanel> <listbox> <listboxitem view:gridbehavior.istextmatch="true" view:gridbehavior.cellscounter="{staticresource counterkey}" content="a"/> <listboxitem view:gridbehavior.istextmatch="false" view:gridbehavior.cellscounter="{staticresource counterkey}" content="b"/> <listboxitem view:gridbehavior.istextmatch="false" view:gridbehavior.cellscounter="{staticresource counterkey}" content="c"/> <listboxitem view:gridbehavior.istextmatch="true" view:gridbehavior.cellscounter="{staticresource counterkey}" content="d"/> </listbox> <textblock text="{binding path=count,source={staticresource counterkey}}"/> </stackpanel> </window> n.b. need go further , enhance remove logic. example, if remove item istextmatch=true list, doesn't affect counter. believe, skilled enough yourself.
Comments
Post a Comment