Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Wednesday, April 6, 2011

Animate Image Left To Right

The basics of any animation is moving something from one location to the other. In this code snippet I use to Image elements to slide away previously selected image and slide in the newly selected one.


The Image elements need to sit in a Canvas in order to let the Left property make sence.
<Label x:Name="txtFile"  HorizontalAlignment="Stretch"  />
<Canvas HorizontalAlignment=
"Stretch" VerticalAlignment="Stretch">

<Image x:Name=
"newImage" Canvas.Left="0" Canvas.Top="0" />
<Image x:Name=
"oldImage" Canvas.Left="0" Canvas.Top="0" />

</Canvas>



assuming that I have already given the previously selected image, my new image file will be given through a function call like
AnimateLeftToRight(selectedFile);

This method will swap the images and create a storyboard to begin animating. I start the newImage from x-position that equals to minus Window.Width and the old one starts from 0 and moves to Window.Width:


/// <summary>
/// Begins a story which animates two images from left to right
/// the old image takes the source from te new image just before assigning the new one
/// and they move together in the distance of Window.Width
/// </summary>
/// <param name="path">the path of the new image</param>
private void AnimateLeftToRight(string path)
{
oldImage.Source = newImage.Source;
newImage.Source =
new BitmapImage(new Uri(path));

var myStoryboard =
new Storyboard();

myStoryboard.Children.Add(MakeAnimation(-
this.Width, 0, "newImage"));
myStoryboard.Children.Add(MakeAnimation(
0, this.Width, "oldImage"));

myStoryboard.Begin(
this);
}



Making animation can be done in different ways using different EasingFunction, But this one looked easy to understand and look nice on my example:


/// <summary>
/// Creates a DoubleAnimation that moves the target from left to right
/// </summary>
/// <param name="from">starting point X</param>
/// <param name="to">ending point X</param>
/// <param name="target">the target element to set the x to </param>
/// <returns>the created animation</returns>
private DoubleAnimation MakeAnimation(double from, double to, string target)
{
const double durationSeconds = 1;

var animation =
new DoubleAnimation
{
Duration =
new Duration(TimeSpan.FromSeconds(durationSeconds)),
AutoReverse =
false,
From = from,
To = to,
EasingFunction =
new PowerEase()
{
EasingMode = EasingMode.EaseInOut,
Power =
5
}
};

Storyboard.SetTargetName(animation, target);
Storyboard.SetTargetProperty(animation,
new PropertyPath(Canvas.LeftProperty));

return animation;
}


Tuesday, March 15, 2011

Geometry and Mini-Language

StreamGeometry is a light-weight alternative to the PathGeometry class for
creating complex geometric shapes. You can use StreamGeometry when you
need to describe a complex geometry but don’t want the overhead of supporting
data binding, animation, and modification.

There are two classes in WPF that provide the mini-language for describing
geometric paths: StreamGeometry, and PathFigureCollection. You need to use
the StreamGeometry mini-language when you set a property of the Geometry
type, such as the Data property of a Path element.

<path stroke="Blue" data="M 100 120 L 200 120 L 200 220 L 100 170">
</path>


This path uses a sequence of four commands. The first command, M, creates the
PathFigure and sets the starting point to (100, 120). The following three
commands (L) create line segments.

See also Mini-Language in MSDN
From the book of Practical WPF Graphics Programming



L endPoint : The end point of the line.
H x : The x-coordinate of the end point of the line.
V y : The y-coordinate of the end point of the line.

F0 specifies the EvenOdd fill rule.
F1 specifies the Nonzero fill rule.
An uppercase M indicates that startPoint is an absolute value; a lowercase m indicates that startPoint is an offset to the previous point

C controlPoint1 controlPoint2 endPoint : Cubic Bezier Curve Command
A size rotationAngle isLargeArcFlag sweepDirectionFlag endPoint : Creates an elliptical arc between the current point and the specified end point.

Z : Ends the current figure and creates a line that connects the current point to the starting point of the figure.

Monday, December 6, 2010

Introducing Custom DependencyProperty in WPF

In this sample code I want to introduce three DependencyProperty called Overlap Rotation and UpperOffset in a custom control OverlapStackPannel. The control is simply a StackPanel that arranges the containing items in a custom manner.

In the ArrageOverride method I will use these three properties to locate each item as follows:



   protected  override  System.Windows.Size  ArrangeOverride(System.Windows.Size  arrangeSize)
   {
     UIElementCollection  children = this.InternalChildren;

    int  childrenResolved = 0;
    foreach  (UIElement  child in  children)
    {
 Rect  targetRect = new  Rect ();
 targetRect.X = this .Overlap * childrenResolved;
 targetRect.Y = this .UpperOffset;
 targetRect.Width = child.DesiredSize.Width;
 targetRect.Height = child.DesiredSize.Height;
 child.Arrange(targetRect);
 child.RenderTransform = new  RotateTransform (this .Rotation);
 childrenResolved++;
    }
    return  arrangeSize;
   }



To Achieve this I need to set the properties as follows:


  #region  Property: UpperOffset
  public  static  readonly  DependencyProperty  UpperOffsetProperty = DependencyProperty .Register("UpperOffset" , typeof (double ), typeof (OverlapStackPanel ), new  FrameworkPropertyMetadata (double .NaN, FrameworkPropertyMetadataOptions .AffectsArrange));
      
  /// <summary> 
  /// set or get the upper offset for each item in the pannel 
  /// </summary> 
  public  double  UpperOffset
  {
    get 
    {
      return  (double )this .GetValue(OverlapStackPanel .UpperOffsetProperty);
    }
    set 
    {
      this .SetValue(OverlapStackPanel .UpperOffsetProperty, value );
    }
  }
  #endregion 



and similar for other two.
This makes my OverlapStackPanel having the properties in Blend like this:



Benefits


According to this nice article there are three main advantages of using DependencyProperties comparing to CLR properties:

  • Reduced memory footprint

  • Value inheritance

  • Change notification