WPF - анимация в пользовательском элементе управления, обучение, попытка понять, но чувство n00bish - PullRequest
1 голос
/ 05 декабря 2008

ОК, я переделываю это, так как испортил. :) вот хамл.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="ucWaitIndicator.Window1"
    x:Name="Window"
    Title="Window1"
    Width="640" Height="480">
    <Window.Resources>
        <Storyboard x:Key="OnLoaded1">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="path" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" RepeatBehavior="Forever">
                <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="360"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
        </EventTrigger>
    </Window.Triggers>

    <Grid x:Name="LayoutRoot">
        <Path Data="M180.99244,64C116.37543,64 63.992443,116.38299 63.992443,181 63.992443,245.61742 116.37549,298 180.99244,298 245.60981,298 297.99244,245.61737 297.99244,181 297.99244,116.38304 245.60986,64 180.99244,64z M180.99244,0.5C205.91427,0.5 229.65641,5.5507355 251.25119,14.684582 256.64987,16.968037 261.91435,19.506668 267.02946,22.285378 307.95065,44.515015 339.31398,82.108706 353.37751,127.32482 356.89353,138.6289 359.32811,150.40922 360.56053,162.54492 361.79308,174.68071 361.79307,187.31935 360.56053,199.45508 355.63085,247.99793 331.46539,290.85483 295.8072,320.28259 277.97817,334.9964 257.2756,346.35331 234.66763,353.38507 223.36361,356.90106 211.58325,359.33566 199.44752,360.56808 187.31179,361.80063 174.67315,361.80063 162.53737,360.56808 113.99482,355.63844 71.137715,331.47319 41.70987,295.81476 26.995966,277.98571 15.63918,257.28314 8.6073667,234.67519 5.0914601,223.37117 2.6567941,211.59082 1.4243458,199.45508 0.19188775,187.31935 0.19188165,174.68071 1.4243458,162.54492 6.3541056,114.00227 30.519295,71.145355 66.177677,41.717426 84.006863,27.003489 104.70924,15.646738 127.31726,8.6149235 138.62133,5.0989907 150.40165,2.6643478 162.53737,1.4319025 168.60525,0.81567122 174.76199,0.5 180.99244,0.5z" Margin="10,10,0,0" x:Name="path" RenderTransformOrigin="0.5,0.5" Stretch="Fill" Stroke="Black" Height="77" HorizontalAlignment="Left" VerticalAlignment="Top" Width="77" MouseLeftButtonDown="path_MouseLeftButtonDown" MouseRightButtonDown="path_MouseRightButtonDown">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="1" />
                    <SkewTransform AngleX="0" AngleY="0" />
                    <RotateTransform Angle="0" />
                    <TranslateTransform X="0" Y="0" />
                </TransformGroup>
            </Path.RenderTransform>
            <Path.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="#FF7E7E7E" Offset="1" />
                </LinearGradientBrush>
            </Path.Fill>
        </Path>
    </Grid>
</Window>

Это непрерывная анимация. В коде у меня есть следующее:

public partial class Window1 : Window
{
public Storyboard myStoryboard;

public Window1()
    {
        this.InitializeComponent();

        // Insert code required on object creation below this point.
    myStoryboard = (Storyboard)TryFindResource("OnLoaded1");
    myStoryboard.Begin();
}

private void path_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    myStoryboard.Begin();
}


private void path_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    myStoryboard.Stop();

}

}

Я получаю действительно спорадический контроль, используя методы start и stop. Иногда остановка работает, но только если я сначала сделал правый клик. Я не понимаю, почему STOP не останавливает его, а start не запускает его?

Спасибо, ребята.

Ответы [ 4 ]

2 голосов
/ 08 декабря 2008

Это работает именно так, как я и ожидал. Дайте мне знать, если вам нужно больше информации о том, что я сделал. Все сводится к тому, как ведут себя раскадровки XAML. Сначала они могут быть немного хитрыми, потому что поведение Begin / Stop / Pause / Resume не совсем очевидно. Вы не можете приостановить / возобновить, если он еще не запущен, и (в Silverlight) вы не можете снова начать раскадровку, если вы на самом деле не остановите его. Таким образом, функция цикла имеет обе эти строки

// Silverlight ONLY    
storyboard.Stop(); 
storyboard.Begin();

К счастью, WPF не заставляет вас это делать.

public partial class Window1 : Window
    {
        public Storyboard myStoryboard;

        public Window1()
        {
            this.InitializeComponent();

            // Insert code required on object creation below this point.
            myStoryboard = (Storyboard)TryFindResource("OnLoaded1");
            // This will loop your storyboard endlessly so you can use the Pause/Resume functions
            myStoryboard.Completed += new EventHandler(myStoryboard_Completed);
            // Begin the animation and immediately Pause it.
            myStoryboard.Begin();
            myStoryboard.Pause();
        }

        void myStoryboard_Completed(object sender, EventArgs e)
        {
            myStoryboard.Begin();

        }

        private void path_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
           // Start the spinning again 
           myStoryboard.Resume();
        }


        private void path_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
           // Pause the Spinning.
            myStoryboard.Pause();

        }

    }

Вам также необходимо удалить триггер события и запустить раскадровку из кода, который находится позади.

 <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <!-- REMOVE THIS LINE
                   <BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
                    -->
        </EventTrigger>
    </Window.Triggers>
2 голосов
/ 05 декабря 2008

Вы хотите сделать это в XAML или в коде c # позади?

Оба метода могут обеспечить большую гибкость анимации.

Вот решение для раскадровки XAML, дайте мне знать, если вам нужна чистая версия c #.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Media.Animation;
using System.Windows.Resources;
using System.Windows.Markup;
// Make sure to include this reference to use Storyboard Class
using System.Windows.Media.Animation;


namespace StoryboardSample
{
    public partial class Window1 : Window
 {
        // Set up the Storyboard variable
        public Storyboard myStoryboard;
        public Window1()
  {
   this.InitializeComponent();

   // Assign the Storyboard to the variable.
            myStoryboard = (Storyboard)TryFindResource("myStoryboard");
            myFunction();

  }
        public void myFunction()
        {
            // Begin the Animation
            myStoryboard.Begin();
        }
 }
}


<Window
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Class="StoryboardSample.Window1"
 x:Name="Window"
 Title="Window1"
 Width="640" Height="480">
 <Window.Resources>
  <Storyboard x:Key="myStoryboard">
   <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="myRect" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="-71"/>
   </DoubleAnimationUsingKeyFrames>
  </Storyboard>
 </Window.Resources>
 <Grid x:Name="LayoutRoot">
 <Rectangle x:Name="myRect" Fill="Black" Width="300" Height="150" RenderTransformOrigin="0.5,0.5" >
  <Rectangle.RenderTransform>
   <TransformGroup>
    <ScaleTransform ScaleX="1" ScaleY="1"/>
    <SkewTransform AngleX="0" AngleY="0"/>
    <RotateTransform Angle="0"/>
    <TranslateTransform X="0" Y="0"/>
   </TransformGroup>
  </Rectangle.RenderTransform>
 </Rectangle>
 </Grid>
</Window>

У меня есть запись в моем блоге с чуть более подробным описанием этого кода.

1 голос
/ 05 декабря 2008

У вас еще нет ничего, чтобы начать или остановить. Вам нужна раскадровка. Начните с этого Обзор анимации (msdn)

0 голосов
/ 05 декабря 2008

Посмотрите на индикатор ожидания в приложении Silverlight 2 Криса Андерсона : (Полный исходный код и демонстрационная версия доступны по ссылке.)

<!-- Created by Chris Anderson: http://chrisa.wordpress.com -->
<UserControl x:Class="SilverlightLOBFramework.Controls.Layout.WaitIndicator"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="30" Height="30">

    <UserControl.Resources>
        <Storyboard x:Name="IndicatorStoryboard">
            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse1"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse2"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse3"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse4"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse5"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse6"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse7"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>

            <ColorAnimationUsingKeyFrames 
                                  Storyboard.TargetName="Ellipse8"
                                  Storyboard.TargetProperty="(Fill).(SolidBrush.Color)"
                                  BeginTime="0" RepeatBehavior="Forever">

                <LinearColorKeyFrame Value="#9CFFFFFF" KeyTime="00:00:00" />
                <LinearColorKeyFrame Value="#6DFFFFFF" KeyTime="00:00:00.15" />
                <LinearColorKeyFrame Value="#3EFFFFFF" KeyTime="00:00:00.3" />
                <LinearColorKeyFrame Value="#2EFFFFFF" KeyTime="00:00:00.45" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.60" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.75" />
                <LinearColorKeyFrame Value="#1EFFFFFF" KeyTime="00:00:00.90" />
                <LinearColorKeyFrame Value="#CCFFFFFF" KeyTime="00:00:01.05" />
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>

    <Canvas x:Name="LayoutRoot">
        <Ellipse x:Name="Ellipse1" Fill="#1EFFFFFF" Canvas.Left="0" Canvas.Top="11" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse2" Fill="#1EFFFFFF" Canvas.Left="3" Canvas.Top="3" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse3" Fill="#1EFFFFFF" Canvas.Left="11" Canvas.Top="0" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse4" Fill="#2EFFFFFF" Canvas.Left="19" Canvas.Top="3" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse5" Fill="#3EFFFFFF" Canvas.Left="22" Canvas.Top="11" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse6" Fill="#6DFFFFFF" Canvas.Left="19" Canvas.Top="19" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse7" Fill="#9CFFFFFF" Canvas.Left="11" Canvas.Top="22" Height="8" Width="8"></Ellipse>
        <Ellipse x:Name="Ellipse8" Fill="#CCFFFFFF" Canvas.Left="3" Canvas.Top="19" Height="8" Width="8"></Ellipse>
    </Canvas>
</UserControl>

using System.Windows;
using System.Windows.Controls;

namespace SilverlightLOBFramework.Controls.Layout
{
    public partial class WaitIndicator : UserControl
    {
        #region Constructor
        public WaitIndicator()
        {
            InitializeComponent();

            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                LayoutRoot.Visibility = Visibility.Collapsed;
        } 
        #endregion

        #region Public Functions
        public void Start()
        {
            LayoutRoot.Visibility = Visibility.Visible;
            IndicatorStoryboard.Begin();
        }

        public void Stop()
        {
            LayoutRoot.Visibility = Visibility.Collapsed;
            IndicatorStoryboard.Stop();
        } 
        #endregion
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...