The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Animationen mit WPF anhand einer kleinen Foto Gallery

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
-

Posts: 1524
Nickname: nitronic
Registered: Jul, 2006

Norbert Eder works as a software architect.
Animationen mit WPF anhand einer kleinen Foto Gallery Posted: Jan 24, 2008 1:33 PM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by -.
Original Post: Animationen mit WPF anhand einer kleinen Foto Gallery
Feed Title: Norbert Eder - Living .NET
Feed URL: http://feeds.feedburner.com/NorbertEder-Livingnet
Feed Description: Copyright (c)2005, 2006 by Norbert Eder
Latest .NET Buzz Posts
Latest .NET Buzz Posts by -
Latest Posts From Norbert Eder - Living .NET

Advertisement

Einleitung


Animationen mittels WPF sind nicht schwer. Dieser Artikel soll eine kleine Einführung liefern und zeigen, wie einfach eine kleine Animation mit Fotos gemacht werden kann. Das Resultat ist nachfolgend kurz zu sehen.


Erste Schritte


Bevor es an die Animation selbst geht, entwerfen wir ein UserControl, welches für die Darstellung der Fotos zuständig ist. Hier auch gleich der entsprechende Code.

XAML
<UserControl x:Class="WpfAnimationDemo.PictureControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <DockPanel>
        <DockPanel Background="Black">
            <Image x:Name="ImageControl" Margin="5"/>
        </DockPanel>
    </DockPanel>
</UserControl>


Code-Behind
public partial class PictureControl : UserControl
{
    private Size _originSize;
    private Point _originLocation;

    public static DependencyProperty OriginSizeProperty = 
        DependencyProperty.Register(
            "OriginSize", 
            typeof(Size), typeof(Size));
    public static DependencyProperty OriginLocationProperty = 
        DependencyProperty.Register(
        "OriginLocation", 
        typeof(Point), typeof(Point));

    public PictureControl()
    {
        InitializeComponent();
    }

    public void SetImage(string path)
    {
        ImageControl.Source = BitmapFrame.Create(new Uri(path));
    }

    public Size OriginSize
    {
        get { return _originSize; }
        set { this._originSize = value; }
    }

    public Point OriginLocation
    {
        get { return _originLocation; }
        set { _originLocation = value; }
    }
}

Darin befinden sich keine Besonderheiten. Es wird lediglich eine Eigenschaft SetImage angeboten. Darüber kann das gewünschte Foto gesetzt und somit angezeigt werden.

Weiters wird dieses erstellte Control nun in ein Window eingebettet, damit auch tatsächlich Fotos angezeigt werden können. In dieser Demoanwendung werden insgesamt vier Fotos dargestellt - also wenig dynamisch.

Hier nun das XAML für das Fenster:
<Window x:Class="WpfAnimationDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfAnimationDemo"
    Title="Picture Animation Demo" Height="570" Width="800">
    <Canvas>
        <local:PictureControl 
            x:Name="PicControl1" 
            HorizontalAlignment="Left" 
            Width="160" 
            Height="120" 
            Canvas.Left="10" 
            Canvas.Top="10" />
        <local:PictureControl 
            x:Name="PicControl2" 
            HorizontalAlignment="Left" 
            Width="160" 
            Height="120" 
            Canvas.Left="10" 
            Canvas.Top="140"/>
        <local:PictureControl 
            x:Name="PicControl3" 
            HorizontalAlignment="Left" 
            Width="160" 
            Height="120" 
            Canvas.Left="10" 
            Canvas.Top="270" />
        <local:PictureControl 
            x:Name="PicControl4" 
            HorizontalAlignment="Left" 
            Width="160" 
            Height="120" 
            Canvas.Left="10" 
            Canvas.Top="400" />
    </Canvas>
</Window>


Da nun die grundlegenden Arbeiten erledigt sind, werden wir uns dem Thema Animation zuwenden.

Animation erstellen


Wichtigster Bestandteil für eine Animation ist das Storyboard. Dabei handelt es sich um eine Timeline, die auf einzelne Elemente und dazugehörige Animationen verweist. Mittels Begin werden die in einem Storyboard enthaltenen Animationen ausgeführt. Der Ablauf des StoryBoards kann mittels Stop angehalten werden. Weiters stehen Pause, Resume und Seek zur Verfügung. Zusätzlich stehen Events zur Verfügung, um beispielsweise auf die Beendigung des Durchlaufs eines Storyboards reagieren zu können. Es empfiehlt sich einen Blick auf die Storyboard Übersicht zu werfen.

Durch die WPF werden bereits einige vordefinierte Animationen unterstützt. Diese leiten von AnimationTimeline. Diese Klasse basiert wiederum auf Timeline.

Folgende Ableitungen von AnimationTimeline stehen zur Verfügung, worauf dann weitere Timelines basieren.
  • DoubleAnimationBase
  • BooleanAnimationBase
  • ByteAnimationBase
  • CharAnimationBase
  • ColorAnimationBase
  • DecimalAnimationBase
  • Int16AnimationBase
  • Int32AnimationBase
  • Int64AnimationBase
  • MatrixAnimationBase
  • ObjectAnimationBase
  • Point3DAnimationBase
  • PointAnimationBase
  • QuaternionAnimationBase
  • RectAnimationBase
  • Rotation3DAnimationBase
  • SingleAnimationBase
  • SizeAnimationBase
  • StringAnimationBase
  • Vector3DAnimationBase
  • VectorAnimationBase

In unserem Beispiel wird DoubleAnimation verwendet (basiert auf DoubleAnimationBase). Jede dieser Animationen beschränkt sich (wie zu sehen ist) auf einen bestimmten Typ, welcher verändert werden kann.

Hier ein Beispiel zur Verdeutlichung:
DoubleAnimation doubleAnimHeight = new DoubleAnimation();
doubleAnimHeight.From = 10;
doubleAnimHeight.To = 100;
doubleAnimHeight.Duration = new Duration(
    TimeSpan.FromSeconds(0.5));

Diese defnierte DoubleAnimation bewirkt, dass innerhalb einer bestimmten Duration (also Zeitpannse) der Wert von 10 auf 100 erhöht wird. Andere Animationen funktionieren auf dieselbe Art und Weise.

Im zugrunde liegenden Beispiel soll nun bei einem Klick auf ein Foto, dieses in den Contentbereich verschoben und vergrößert werden. Bei nochmaligem Klick, soll sich das Foto an die ursprüngliche Position zurück animieren. Dafür benötigen wir wir insgesamt vier DoubleAnimations, jeweils für die Höhe, Breite, Top-Position und Left-Position:
DoubleAnimation doubleAnimWidth = new DoubleAnimation();
doubleAnimWidth.From = picControl.Width;
doubleAnimWidth.To = size.Width;
doubleAnimWidth.Duration = new Duration(
    TimeSpan.FromSeconds(0.5));

DoubleAnimation doubleAnimHeight = new DoubleAnimation();
doubleAnimHeight.From = picControl.Height;
doubleAnimHeight.To = size.Height;
doubleAnimHeight.Duration = new Duration(
    TimeSpan.FromSeconds(0.5));

DoubleAnimation doubleAnimTop = new DoubleAnimation();
doubleAnimTop.From = Canvas.GetTop(picControl);
doubleAnimTop.To = location.Y;
doubleAnimTop.Duration = new Duration(
    TimeSpan.FromSeconds(0.5));

DoubleAnimation doubleAnimLeft = new DoubleAnimation();
doubleAnimLeft.From = Canvas.GetLeft(picControl);
doubleAnimLeft.To = location.X;
doubleAnimLeft.Duration = new Duration(
    TimeSpan.FromSeconds(0.5));

Wie zu sehen ist, werden die Eigenschaften From und To nicht fix zugewiesen, sondern stammen von einer zuvor definierten Logik:
PictureControl picControl = (PictureControl)sender;

Point location = new Point(
    Canvas.GetLeft(picControl), 
    Canvas.GetTop(picControl));
Size size = new Size(
    picControl.ActualWidth, 
    picControl.ActualHeight);

if (location != _targetLocation)
{
    location = _targetLocation;
    size = _targetSize;
}
else
{
    location = picControl.OriginLocation;
    size = picControl.OriginSize;
}

Zu beachten ist, dass sich dieser Code im MouseDown-Eventhandler befindet. Bei der Instanzierung der Picture-Steuerelemente wird die ursprüngliche Position und Größe gesetzt. Mit lokalen Variablen kann nun die aktuelle Position abgefragt werden, entspricht diese der Position des Contentbereichs, muss das Foto wieder an den ursprünglichen Platz zurück animiert werden, andernfalls ist der Contentbereich zu füllen.

Im abschließenden Schritt muss noch das Storyboard mit den Animationen und den notwendigen Zuweisungen gefüttert werden:
board.Children.Clear();
board.Children.Add(doubleAnimWidth);
board.Children.Add(doubleAnimHeight);
board.Children.Add(doubleAnimTop);
board.Children.Add(doubleAnimLeft);

Storyboard.SetTargetName(
    doubleAnimWidth, 
    picControl.Name);
Storyboard.SetTargetName(
    doubleAnimHeight, 
    picControl.Name);
Storyboard.SetTargetName(
    doubleAnimLeft, 
    picControl.Name);
Storyboard.SetTargetName(
    doubleAnimTop, 
    picControl.Name);

Storyboard.SetTargetProperty(
    doubleAnimWidth, 
    new PropertyPath(PictureControl.WidthProperty));
Storyboard.SetTargetProperty(
    doubleAnimHeight, 
    new PropertyPath(PictureControl.HeightProperty));
Storyboard.SetTargetProperty(
    doubleAnimLeft, 
    new PropertyPath(Canvas.LeftProperty));
Storyboard.SetTargetProperty(
    doubleAnimTop, 
    new PropertyPath(Canvas.TopProperty));

board.Begin(this);

Zuerst werden alle Kindelemente unseres Storyboard namens board mittels Clear gelöscht und alle zuvor definierten Animationen hinzugefügt. Danach muss das Zielelement definiert werden. Dieses wird beim MouseDown-Event durch das Objekt sender präsentiert, worüber wir den Namen des Objektes abfragen und dem Storyboard mittels SetTargetName übermitteln. Hier muss auch die entsprechende Animation als Parameter übergeben werden, damit das Storyboard weiß, welche Animation auf welches Element angewandt werden muss.

Ist dies erledigt, muss dem Storyboard noch mitgeteilt werden, welche Properties durch die Animationen betroffen sind. Hier gilt es nun, ebenfalls pro Animation den PropertyPath des Zielelementes zu definieren.

Schlussendlich wird das Storyboard mittels Begin gestartet.

Fazit


Dies war eine kurze Einführung in die Welt der Animationen unter WPF. Natürlich sind weitaus komplexere Animation möglich. Auf dieser Basis ist es aber möglich, sich weiter in dieses Thema zu vertiefen und verbesserte Lösungen zu schaffen.

Download Beispielanwendung

Read: Animationen mit WPF anhand einer kleinen Foto Gallery

Topic: Globales Exception-Handling in WPF Previous Topic   Next Topic Topic: SharePoint Silverlight Browser

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use