c# - CustomControl Slide Window -


due other reasons need wpf customcontrol. goal slide window, has property isactive.

if property changed true, slide window slide in left right. if property changed true, slidewindow slide out.

this functionality works fine (i triggers in xaml file). need set visibility visibile (before slide in effect starts) or collapsed (after slide out effect finished). , problem.


slidewindowcontrol.cs

using system; using system.windows; using system.windows.controls;  namespace slidewindowtest {     public class slidewindowcontrol : contentcontrol     {         public static readonly dependencyproperty isactiveproperty = dependencyproperty.register(           "isactive", typeof(boolean), typeof(slidewindowcontrol), new propertymetadata(true));          static slidewindowcontrol()         {             defaultstylekeyproperty.overridemetadata(typeof(slidewindowcontrol), new frameworkpropertymetadata(typeof(slidewindowcontrol)));         }          public boolean isactive         {             { return (boolean)getvalue(isactiveproperty); }             set { setvalue(isactiveproperty, value); }         }     } } 

corresponding generic.xaml slidewindowcontrol

<resourcedictionary     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="clr-namespace:slidewindowtest">      <style targettype="{x:type local:slidewindowcontrol}">         <setter property="rendertransform">             <setter.value>                 <scaletransform scalex="1"/>             </setter.value>         </setter>         <setter property="template">             <setter.value>                 <controltemplate targettype="{x:type local:slidewindowcontrol}">                     <border background="{templatebinding background}"                             borderbrush="{templatebinding borderbrush}"                             borderthickness="{templatebinding borderthickness}"                             x:name="root">                         <stackpanel orientation="vertical">                             <grid background="black">                                 <textblock text="header" foreground="white" margin="17" fontsize="20pt" />                             </grid>                             <contentpresenter />                         </stackpanel>                     </border>                      <controltemplate.triggers>                         <trigger property="isactive" value="true">                              <!-- show -->                             <trigger.enteractions>                                 <beginstoryboard>                                     <storyboard>                                         <!-- visibility change cause trouble                                         <objectanimationusingkeyframes storyboard.targetproperty="visibility" duration="0" begintime="0">                                             <discreteobjectkeyframe value="{x:static visibility.visible}" />                                         </objectanimationusingkeyframes>                                         -->                                          <doubleanimation storyboard.targetproperty="rendertransform.scalex" from="0" duration="0:00:00.5" />                                     </storyboard>                                 </beginstoryboard>                             </trigger.enteractions>                              <!-- hide -->                             <trigger.exitactions>                                 <beginstoryboard>                                     <storyboard>                                         <doubleanimation storyboard.targetproperty="rendertransform.scalex" from="1" to="0" duration="0:00:00.5"/>                                          <!-- visibility change cause trouble                                         <objectanimationusingkeyframes storyboard.targetproperty="visibility" duration="0" begintime="0:00:00.5">                                             <discreteobjectkeyframe value="{x:static visibility.collapsed}" />                                         </objectanimationusingkeyframes>                                         -->                                     </storyboard>                                 </beginstoryboard>                             </trigger.exitactions>                         </trigger>                     </controltemplate.triggers>                 </controltemplate>             </setter.value>         </setter>     </style> </resourcedictionary> 

example of use slidewindowcontrol in mainwindow.xaml

<window x:class="slidewindowtest.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:local="clr-namespace:slidewindowtest"         title="mainwindow" height="350" width="525">     <stackpanel orientation="vertical">         <stackpanel orientation="horizontal">             <button content="slide in" click="slideinbutton_click"/> <!-- inmainwindow.xaml.cs set myslidewindow.isactive = true; -->             <button content="slide out" click="slideoutbutton_click" /> <!-- inmainwindow.xaml.cs set myslidewindow.isactive = false; -->         </stackpanel>          <local:slidewindowcontrol x:name="myslidewindow">             <textblock fontsize="40pt">super content!</textblock>         </local:slidewindowcontrol>     </stackpanel> </window> 

i try set visibility property in triggers in generic.xaml slidewindowcontrol (see in commented code please), breaks whole trigger (no animation effect shown).

how can achieve change of visibility property? need bind visibility property in other components.

a solution be:

  1. create 2 storyboards static resources , reference them in beginstoryboard-storyboard ({staticresource slidein}) instead of having them inline children.

  2. implement completed event

  3. in completed-eventhandler set visibility collapsed when isactive = false.
  4. in fadein-click event, you'll have set visibility visible before set isactive = true.

this little asymmetric works in test case.

    <window x:class="so38699140.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"         xmlns:local="clr-namespace:so38699140"         mc:ignorable="d"         title="mainwindow" height="350" width="525">   <window.resources>      <storyboard x:key="slidein" completed="storyboard_completed" >       <doubleanimation storyboard.targetproperty="rendertransform.scalex" from="0" duration="0:00:00.5"  />     </storyboard>      <storyboard x:key="slideout" completed="storyboard_completed">       <doubleanimation storyboard.targetproperty="rendertransform.scalex" from="1" to="0" duration="0:00:00.5" />     </storyboard>       <style targettype="{x:type local:slidewindowcontrol}">       <setter property="rendertransform">         <setter.value>           <scaletransform scalex="1"/>         </setter.value>       </setter>       <setter property="template">         <setter.value>           <controltemplate targettype="{x:type local:slidewindowcontrol}">             <border background="{templatebinding background}"                             borderbrush="{templatebinding borderbrush}"                             borderthickness="{templatebinding borderthickness}"                             x:name="root">               <stackpanel orientation="vertical">                 <grid background="black">                   <textblock text="header" foreground="white" margin="17" fontsize="20pt" />                 </grid>                 <contentpresenter />               </stackpanel>             </border>              <controltemplate.triggers>               <trigger property="isactive" value="true">                  <!-- show -->                 <trigger.enteractions>                   <beginstoryboard storyboard="{staticresource slidein}">                   </beginstoryboard>                 </trigger.enteractions>                  <!-- hide -->                 <trigger.exitactions>                   <beginstoryboard storyboard="{staticresource slideout}">                   </beginstoryboard>                 </trigger.exitactions>               </trigger>             </controltemplate.triggers>           </controltemplate>         </setter.value>       </setter>     </style>   </window.resources>     <stackpanel orientation="vertical">       <stackpanel orientation="horizontal">         <button content="slide in" click="slideinbutton_click"/>         <!-- inmainwindow.xaml.cs set myslidewindow.isactive = true; -->         <button content="slide out" click="slideoutbutton_click" />         <!-- inmainwindow.xaml.cs set myslidewindow.isactive = false; -->       <textblock text="{binding elementname=myslidewindow, path=visibility}" />      </stackpanel>        <local:slidewindowcontrol x:name="myslidewindow">         <textblock fontsize="40pt">super content!</textblock>       </local:slidewindowcontrol>   </stackpanel> </window>          }      private void slideinbutton_click(object sender, routedeventargs e)     {       myslidewindow.visibility = visibility.visible;       myslidewindow.isactive = true;     }      private void slideoutbutton_click(object sender, routedeventargs e)     {       myslidewindow.isactive = false;     }      private void storyboard_completed(object sender, eventargs e)     {       if (!myslidewindow.isactive)         myslidewindow.visibility = visibility.collapsed;      } 

Comments