c# - Eliminating the Storyboard Completed handler in code behind -


a little background:

i'm building window , i've got storyboard use show briefly popup upon completion of user-initiated task without need user confirmation. looks so:

<usercontrol.resources>     <storyboard x:name="fadingfeedback" x:key="fadingfeedback" completed="fadingfeedback_completed">         <doubleanimation                            storyboard.targetproperty="opacity"                           from="0.5"                           to="0"                           begintime="0:0:0"                           duration="0:0:2.0">             <doubleanimation.easingfunction>                 <exponentialease exponent="10" easingmode="easein" />             </doubleanimation.easingfunction>         </doubleanimation>     </storyboard> </usercontrol.resources> 

the popup i'm using defined so:

<popup name="popup" placement="center" popupanimation="fade" allowstransparency="true"        isopen="{binding doshowmessage}">     <popup.style>         <style>             <style.triggers>                 <datatrigger binding="{binding doshowmessage}" value="true">                     <setter property="popup.isopen" value="true" />                     <datatrigger.enteractions>                         <beginstoryboard storyboard="{staticresource fadingfeedback}" />                     </datatrigger.enteractions>                 </datatrigger>             </style.triggers>         </style>     </popup.style>     <border background="black" borderbrush="white" borderthickness="1" cornerradius="5">         <grid background="transparent">             <grid name="popupgrid" background="black" grid.column="0" grid.row="0" />             <label name="popuplabel" horizontalalignment="center" foreground="white"                    verticalalignment="center"                    background="transparent"                    grid.column="0"                    grid.row="0"                fontsize="16"                content="{binding textmessage}"/>         </grid>     </border> </popup> 

there's viewmodel datacontext , it's got couple of properties (referenced there in bindings) provide textmessage string , doshowmessage bool. defined this:

    private string _textmessage;     public string textmessage     {         { return _textmessage; }         set         {             _textmessage = value;             onpropertychanged("textmessage");         }     }      private bool _doshowmessage;     public bool doshowmessage     {         { return _doshowmessage; }         set         {             _doshowmessage = value;             onpropertychanged("doshowmessage");         }     } 

and when appropriate viewmodel set doshowmessage property , binding in xaml show popup , begin storyboard.

right now, i've got completed handler in code behind popup this:

    void statusfader_completed(object sender, eventargs e)     {         popup.isopen = false;     } 

and works enough, , since popup.isopen bound underlying property on viewmodel doshowmessage, reset boolean.

the question have:

is there "better" way handle reset of doshowmessage property when storyboard done? or perhaps differently put, there way in xaml itself? i've read opinion/convention code behind should (mostly) devoid of code views seems (at least me) (the event handler) reasonable way it. wondering if there's way in xaml though.

yes, of course can in way. setting popup.isopen="false" via objectanimationusingkeyframes.

for example:

storyboard

<storyboard x:name="fadingfeedback" x:key="fadingfeedback">      <doubleanimation storyboard.targetproperty="opacity" from="0.5"                               to="0" begintime="0:0:0" duration="0:0:2.0">          <doubleanimation.easingfunction>             <exponentialease exponent="10" easingmode="easein" />         </doubleanimation.easingfunction>     </doubleanimation>      <objectanimationusingkeyframes begintime="0:0:2.0" storyboard.targetproperty="(popup.isopen)">         <discreteobjectkeyframe keytime="0:0:0">             <discreteobjectkeyframe.value>                 <sys:boolean>false</sys:boolean>             </discreteobjectkeyframe.value>         </discreteobjectkeyframe>     </objectanimationusingkeyframes> </storyboard>  <popup name="popup" placement="center" popupanimation="fade" allowstransparency="true" isopen="{binding doshowmessage}">     <popup.style>         <style>             <style.triggers>                 <datatrigger binding="{binding doshowmessage}" value="true">                 <!--<setter property="popup.isopen" value="true" />--> <!-- not necessarily, because have popup.isopen = true -->                      <datatrigger.enteractions>                         <beginstoryboard storyboard="{staticresource fadingfeedback}" />                     </datatrigger.enteractions>                 </datatrigger>             </style.triggers>             </style>     </popup.style>       ... </popup>         

but in case, opening popup outside animation problematic, because of properties of animation first priority, other sources, such code, designate not. quote msdn:

in order have practical effect, animation of property must able have precedence on base (unanimated) value, if value set locally.

so accessed through code, remove animation property, therefore allowing access property, so:

xaml

<grid>     <grid.triggers>         <eventtrigger sourcename="closebutton" routedevent="button.click">             <beginstoryboard>                 <storyboard>                     <booleananimationusingkeyframes storyboard.targetname="mypopup"                                                     storyboard.targetproperty="(popup.isopen)"                                                      duration="0:0:0">                          <discretebooleankeyframe keytime="0:0:0" value="false" />                     </booleananimationusingkeyframes>                 </storyboard>             </beginstoryboard>         </eventtrigger>     </grid.triggers>      <popup x:name="mypopup" width="200" height="200" isopen="true">         <grid background="azure">             <label content="test label" />         </grid>     </popup>      <button name="openbutton" content="openbuttonfromcode" width="140" height="30" click="openbutton_click" />     <button name="closebutton" content="closebuttonfromeventtrigger" width="180" height="30" margin="0,80,0,0" /> </grid> 

code behind

private void openbutton_click(object sender, routedeventargs e) {     mypopup.beginanimation(popup.isopenproperty, null);     mypopup.isopen = true; }      

there choice, or drop in popup.isopen of false in event storyboard_completed, or in animation, access code, must removed.

for myself, so, create attached dependency property (boolean), bound trigger animation property. if value of true, starts animation, re-run, in event storyboard_completed had fold property false. me, it's easier way.


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -