consider following usercontrol:

this custom usercontrol have written has 2 nested elements.
filtercontent displays special type of markup filters content on right hand side of screen
maincontent hosts filtered content.
the real purpose of control provide consistent ui , animation across application, filter/content pattern used frequently.
the (simplified) xaml of usercontrol follows:
<usercontrol> <grid> <grid.columndefinitions> <columndefinition width="3*"/> <columndefinition width="7*"/> </grid.columndefinitions> <contentpresenter grid.column="0" content="{binding elementname=filtercontrol, path=filtercontrol}" datacontext="{binding}" /> <contentpresenter grid.column="1" content="{binding elementname=filtercontrol, path=maincontrol}" datacontext="{binding}" /> </grid> the codebehind :
public sealed partial class filterpanecontrol : usercontrol { public static dependencyproperty filtercontrolproperty = dependencyproperty.register("filtercontrol", typeof(object), typeof(filterpanecontrol), new propertymetadata(default(object), propertychangedcallback)); public static dependencyproperty maincontrolproperty = dependencyproperty.register("maincontrol", typeof (object), typeof (filterpanecontrol), new propertymetadata(default(object))); public filterpanecontrol() { this.initializecomponent(); } public object filtercontrol { { return (object)getvalue(filtercontrolproperty); } set { setvalue(filtercontrolproperty, value); } } public object maincontrol { { return (object) getvalue(maincontrolproperty); } set { setvalue(maincontrolproperty, value); } } } the usage of control in implementing page :
<generic:filterpanecontrol> <generic:filterpanecontrol.filtercontrol> <grid> <textblock text="filter content here"/> </grid> </generic:filterpanecontrol.filtercontrol> <generic:filterpanecontrol.maincontrol> <grid> <textblock text="main content here"/> </grid> </generic:filterpanecontrol.maincontrol> </generic:filterpanecontrol> that works fine!
the problem
the problem when want reference of content within control implementing page. case visual states handling snap/portrait (winrt implementation)

<generic:filterpanecontrol> <generic:filterpanecontrol.filtercontrol> <grid> <textblock x:name="filtercontent1" text="filter content here"/> </grid> </generic:filterpanecontrol.filtercontrol> <generic:filterpanecontrol.maincontrol> <grid> <textblock text="main content here"/> </grid> </generic:filterpanecontrol.maincontrol> </generic:filterpanecontrol> <visualstatemanager.visualstategroups> <visualstate x:name="fullscreenportrait"> <storyboard> <objectanimationusingkeyframes storyboard.targetname="filtercontent1" storyboard.targetproperty="width"> <discreteobjectkeyframe keytime="0" value="200"/> </objectanimationusingkeyframes> </storyboard> </visualstate> </visualstatemanager.visualstategroups> this leads run-time exception, visualstatemanager cannot find referenced element 'filtercontent1' though exists in visual tree. additionally, if try , reference element directly in page.loaded event handler, filtercontent1 null.
it if nested xaml doesn't render until later - throwing visualstatemanager too.
any suggestions?
first, visualstatemanager should placed in single panel element done, otherwise exception. case turns out this:
<generic:filterpanecontrol> <generic:filterpanecontrol.filtercontrol> <grid> <visualstatemanager.visualstategroups> <visualstate x:name="fullscreenportrait"> <storyboard> <objectanimationusingkeyframes storyboard.targetname="filtercontent1" storyboard.targetproperty="width"> <discreteobjectkeyframe keytime="0" value="200"/> </objectanimationusingkeyframes> </storyboard> </visualstate> </visualstatemanager.visualstategroups> <textblock x:name="filtercontent1" text="filter content here"/> </grid> </generic:filterpanecontrol.filtercontrol> ... second, visualstatemanager placed in either template / style, or usercontrol. transition states carried out either in code or through xaml (with special techniques). sample of set state behind code:
visualstatemanager.gotostate(nameofcontrol, "state1", true); third, in manner:
<storyboard> <objectanimationusingkeyframes storyboard.targetname="filtercontent1" storyboard.targetproperty="width"> <discreteobjectkeyframe keytime="0" value="200"/> </objectanimationusingkeyframes> </storyboard> width not sets, in case exception. need use animation this:
<storyboard storyboard.targetname="filtercontent1" storyboard.targetproperty="width"> <doubleanimation to="200" duration="0:0:1.0"/> </storyboard> as proof of words, give example:
mainwindow
<window x:class="vsminusercontrolhelp.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:vsminusercontrolhelp" title="mainwindow" height="350" width="525" windowstartuplocation="centerscreen"> <grid> <grid.rowdefinitions> <rowdefinition/> <rowdefinition height="40"/> </grid.rowdefinitions> <local:usercontrol1 x:name="control1" height="118" verticalalignment="top" margin="50,12,101,0" /> <stackpanel orientation="horizontal" grid.row="1"> <button name="state1button" width="75" click="state1button_click">state1</button> </stackpanel> </grid> </window> code behind
public partial class mainwindow : window { public mainwindow() { initializecomponent(); } private void state1button_click(object sender, routedeventargs e) { visualstatemanager.gotostate(control1, "state1", true); } } usercontrol
<usercontrol x:class="vsminusercontrolhelp.usercontrol1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:sys="clr-namespace:system;assembly=mscorlib" mc:ignorable="d" d:designheight="300" d:designwidth="300"> <grid> <visualstatemanager.visualstategroups> <visualstategroup x:name="common1"> <visualstate x:name="state1"> <storyboard storyboard.targetname="filtercontent1" storyboard.targetproperty="width"> <doubleanimation to="200" duration="0:0:1.0"/> </storyboard> </visualstate> </visualstategroup> </visualstatemanager.visualstategroups> <textblock x:name="filtercontent1" background="aqua" width="100" horizontalalignment="left" text="filter content here"/> </grid> </usercontrol> note: example run on vs 2010, windows xp, not tested under winrt.
Comments
Post a Comment