WPF Animation based on property value -


i have dependency property double text, , want accomplish rotate (with animation) line text degrees whenever change value of text property.

is there better way implement ontextpropertychanged , there process animation? or done rather in xaml?

here demonstrating code:

mainwindow.xaml

<window         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:l="clr-namespace:wpfapplication1" x:class="wpfapplication1.mainwindow"         title="mainwindow" height="200" width="200" x:name="root">     <grid>         <textbox width="50" height="20" verticalalignment="top"                  text="{binding text, elementname=root, mode=twoway}"/>         <grid width="100" height="100" background="gray" x:name="grid">             <line grid.row="1" x2="100" y2="100" stroke="red"/>         </grid>     </grid> </window> 

and mainwindow.xaml.cs (without usings):

namespace wpfapplication1 {     public partial class mainwindow : window     {         public static readonly dependencyproperty textproperty = dependencyproperty.register(             "text", typeof(double), typeof(mainwindow), new frameworkpropertymetadata(0.0));          public double text         {             { return (double)getvalue(textproperty); }             set { setvalue(textproperty, value); }         }          public mainwindow()         {             initializecomponent();         }     } } 

this possible through binding so:

    <textbox width="50" height="20" verticalalignment="top"              text="{binding path=text, mode=twoway, updatesourcetrigger=propertychanged}"/>     <grid width="100" height="100" background="gray" x:name="grid">         <line grid.row="1" x2="100" y2="100" stroke="red">             <line.rendertransform>                 <rotatetransform centerx="50" centery="50" angle="{binding path=text, mode=oneway, converter={staticresource resourcekey=stod}}"/>             </line.rendertransform>         </line>     </grid> 

your converter has convert string double return system.convert(value.tostring());.

a cool feature discovered while testing this, validation rule automatically added returns validationerror if dont type double value textbox.

to make work have the mainwindows datacontext this.datacontext = this;.

edit: wrote little helper class, animation you:

public class doubleanimationmanager {     private static dictionary<dependencyobject, animationhelper> _helperdic = new dictionary<dependencyobject, animationhelper>();      public static propertypath getproperty(dependencyobject obj)     {         return (propertypath)obj.getvalue(propertyproperty);     }      public static void setproperty(dependencyobject obj, propertypath value)     {         obj.setvalue(propertyproperty, value);     }      public static readonly dependencyproperty propertyproperty = dependencyproperty.registerattached(         "property",         typeof(propertypath),         typeof(doubleanimationmanager),         new propertymetadata(             (o, e) =>             {                 if (!_helperdic.containskey(o))                     _helperdic[o] = new animationhelper(o);                  _helperdic[o].path = (propertypath)e.newvalue;             }));      public static int getdelaytimeinms(dependencyobject obj)     {         return (int)obj.getvalue(delaytimeinmsproperty);     }      public static void setdelaytimeinms(dependencyobject obj, int value)     {         obj.setvalue(delaytimeinmsproperty, value);     }      public static readonly dependencyproperty delaytimeinmsproperty = dependencyproperty.registerattached(         "delaytimeinms",         typeof(int),         typeof(doubleanimationmanager),         new propertymetadata(0,             (o, e) =>             {                 if (!_helperdic.containskey(o))                     _helperdic[o] = new animationhelper(o);                  _helperdic[o].delayinms = (int)e.newvalue;             }));      public static double getvalue(dependencyobject obj)     {         return (double)obj.getvalue(valueproperty);     }      public static void setvalue(dependencyobject obj, double value)     {         obj.setvalue(valueproperty, value);     }      public static readonly dependencyproperty valueproperty = dependencyproperty.registerattached(         "value",         typeof(double),         typeof(doubleanimationmanager),         new propertymetadata(             (o, e) =>             {                 if (!_helperdic.containskey(o))                     _helperdic[o] = new animationhelper(o);                  _helperdic[o].tovalue = (double)e.newvalue;                 if (!_helperdic[o].started)                 {                     _helperdic[o].fromvalue = (double)e.oldvalue;                     _helperdic[o].start();                 }             })); }  public class animationhelper {     private bool _remmode;     private dependencyobject _target;     private backgroundworker _bw = new backgroundworker();     public double fromvalue { get; set; }     private double _tovalue;     public double tovalue      {         { return _tovalue; }         set         {             if (started)             {                 _remmode = true;             }             _tovalue = value;         }     }     public bool started { get; private set; }     private int _delayinms;     public int delayinms      {         { return _delayinms; }         set         {             _delayinms = value;         }     }     public propertypath path { get; set; }      public animationhelper(dependencyobject target)     {         _target = target;         _bw.dowork += delegate         {             system.threading.thread.sleep(delayinms);         };         _bw.runworkercompleted += delegate         {             startanimation();         };     }      private storyboard getstoryboard()     {         storyboard sb = new storyboard();         doubleanimation da = new doubleanimation(tovalue, new timespan(0, 0, 3));         da.from = fromvalue;         storyboard.settarget(da, _target);         storyboard.settargetproperty(da, path);         sb.children.add(da);         sb.completed += delegate         {             if (_remmode)             {                 startanimation();                 _remmode = false;             }             else             {                 started = false;             }         };         return sb;     }      private void startanimation()     {         getstoryboard().begin();         fromvalue = tovalue;     }      public void start()     {         started = true;         _bw.runworkerasync();     } } 

how use it:

    <textbox width="50" height="20" verticalalignment="top"              text="{binding path=text, mode=twoway, updatesourcetrigger=propertychanged}"/>     <grid width="100" height="100" background="gray" x:name="grid">         <line grid.row="1" x2="100" y2="100" stroke="red" local:doubleanimationmanager.property="(uielement.rendertransform).(rotatetransform.angle)" local:doubleanimationmanager.value="{binding path=text, mode=oneway, converter={staticresource resourcekey=stod}}">             <line.rendertransform>                 <rotatetransform centerx="50" centery="50"/>             </line.rendertransform>         </line>     </grid> 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -