c# - Windows Store App Change ItemTemplate OnClick/Dynamically -
i have listview has itemtemplateselector selects template based on data gets service. in case list of items have read vs unread state. selector works on loading, how can change template when user clicks item? want template change when user "reads" data.
view.xaml:
<page.resources> <selectors:myitemtemplateselector x:key="noteitemtemplateselector" readtemplate="{staticresource myreadtemplate}" unreadtemplate="{staticresource myunreadtemplate}"/> </page.resources> <listview x:name="listview1" itemtemplateselector="{staticresource myitemtemplateselector}"/>
you have build in template. suggest creating custom usercontrol data, which, when clicked/tapped/selected, hides 'unread' version , shows 'read' version. can bind starting state data itself, or viewmodel data. like:
<usercontrol xmlns...> <grid> <visualstatemanager.visualstategroups> <visualstategroup x:name="displaystates"> <visualstate x:name="read"> <storyboard> <objectanimationusingkeyframes storyboard.targetproperty="(uielement.visibility)" storyboard.targetname="readcontent"> <discreteobjectkeyframe keytime="0"> <discreteobjectkeyframe.value> <visibility>collapsed</visibility> </discreteobjectkeyframe.value> </discreteobjectkeyframe> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(uielement.visibility)" storyboard.targetname="unreadcontent"> <discreteobjectkeyframe keytime="0"> <discreteobjectkeyframe.value> <visibility>collapsed</visibility> </discreteobjectkeyframe.value> </discreteobjectkeyframe> </objectanimationusingkeyframes> </storyboard> </visualstate> <visualstate x:name="unread"> <storyboard> <objectanimationusingkeyframes storyboard.targetproperty="(uielement.visibility)" storyboard.targetname="unreadcontent"> <discreteobjectkeyframe keytime="0"> <discreteobjectkeyframe.value> <visibility>collapsed</visibility> </discreteobjectkeyframe.value> </discreteobjectkeyframe> </objectanimationusingkeyframes> <objectanimationusingkeyframes storyboard.targetproperty="(uielement.visibility)" storyboard.targetname="readcontent"> <discreteobjectkeyframe keytime="0"> <discreteobjectkeyframe.value> <visibility>collapsed</visibility> </discreteobjectkeyframe.value> </discreteobjectkeyframe> </objectanimationusingkeyframes> </storyboard> </visualstate> </visualstategroup> </visualstatemanager.visualstategroups> <grid x:name:"unreadcontent"> <!--what looks when unread--> </grid> <grid x:name:"readcontent"> <!--what looks when unread--> </grid> </grid> </usercontrol> then, in codebehind of usercontrol, declare dependencyproperty (you can use code snippet 'propdp'):
public bool hasbeenread { { return (bool)getvalue(hasbeenreadproperty); } set { setvalue(hasbeenreadproperty, value); onhasbeenreadchanged(this, value); } } // using dependencyproperty backing store hasbeenread. enables animation, styling, binding, etc... public static readonly dependencyproperty hasbeenreadproperty = dependencyproperty.register("hasbeenread", typeof(bool), typeof(mynewusercontrol), new propertymetadata(false, onhasbeenreadchanged)); then, create propertychanged method switch visual states!
private static void onhasbeenreadchanged(dependencyobject d, dependencypropertychangedeventargs e) { if ((bool)e.newvalue) { visualstatemanager.gotostate(d control, "read", true); } else { visualstatemanager.gotostate(d control, "unread", true); } } this should load properly, default value being false, in case isn't, may need hook in control's loaded event , set visualstate unread there.
lastly, need 1 item template, rid of selector , do:
<listview.itemtemplate> <datatemplate> <!-- you'll have import namespace. also, assumes item --> <!-- (or item vm) has "hasbeenread" bool property --> <namespacewheremycontrolis:myreadunreadcontrol hasbeenread="{binding hasbeenread}"/> </datatemplate> </listview.itemtemplate> oh! there's one more thing do. listview has tell item it's been selected! add selectionchanged eventhandler (it generate 1 you).
private void listview_selectionchanged(object sender, selectionchangedeventargs e) { if(sender != null && sender listview) { if(e.addeditems.count > 0) (e.addeditems[0] mydataordatavmclass).hasbeenread = true; } } your data/vm class need implement inotifypropertychanged. if you're using data vm, should this.
happy coding!
Comments
Post a Comment