2014-04-16 49 views
0

我想要创建图像的幻灯片。为此,我在每次设定的时间间隔后在图像控制中加载了新图像。但每次我加载一个新的图像它没有任何动画,我需要加载每个图像与过渡动画或淡入淡出动画。在Image控件中更改图像时如何实现动画?以下是代码:当在图像控件中加载时动画图像

XAML:

<Grid> 
<Image Source="{Binding CurrentImage}" /> 
</Grid> 

XAML.cs

ViewModel = new ScreenSaverViewModel(); 
this.DataContext = ViewModel; 

ViewModel.cs

/// <summary> 
/// Gets the current image to display on the attract screen. Changes to this property 
/// cause the PropertyChanged event to be signaled 
/// </summary> 
public string CurrentImage 
{ 
    get { return this.currentImage; } 
    protected set 
    { 
     this.currentImage = value; 
     this.OnPropertyChanged("CurrentImage"); 
    } 
} 

/// <summary> 
/// Gets the observable collection of all images. 
/// </summary> 
public ObservableCollection<string> Images 
{ 
    get { return this.images; } 
} 

public ScreenSaverViewModel() 
{ 
    images = new ObservableCollection<string>(); 

    this.LoadSlideShowImages(); 

    if (Images != null && Images.Count > 0) 
    { 
     this.CurrentImage = this.Images[this.currentIndex]; 

     this.tickTimer = new DispatcherTimer(); 
     this.tickTimer.Interval = TimeSpan.FromMilliseconds(TimerIntervalMilliseconds); 
     this.tickTimer.Tick += (s, e) => 
     { 
      this.currentIndex++; 
      this.currentIndex = this.currentIndex < this.Images.Count ? this.currentIndex : 0; 
      this.CurrentImage = this.Images[this.currentIndex]; 
     }; 

     // start the timer after image is loaded 
     this.tickTimer.Start(); 
    } 
} 
+0

使用故事板http://stackoverflow.com/questions/11073573/how-do-i-create-a-rotate-animation-on-an-image-object-using- c-sharp-code-only-i – Sajeetharan

+0

但是,我将如何在新图像的变化上动画?意味着它应该看起来像新的图像加载动画。 –

+0

你可以有两个覆盖图像。淡入顶部图像,设置底部图像,淡出顶部图像,设置顶部图像,重复。 另外[this](http://stackoverflow.com/questions/1165862/animate-wpf-text-when-binding-updates-how)可能会有所帮助。 – DamenEU

回答

4

我创建了一个类继承Image控件中,我曾提出财产变化时图像控制变化的来源。我已经应用了触发器,现在工作正常。以下是代码:

<controls:ImageControl Source="{Binding CurrentImage}" > 
      <controls:ImageControl.Triggers> 
       <EventTrigger RoutedEvent="controls:ImageControl.SourceChanged"> 
        <BeginStoryboard> 
         <Storyboard> 
          <DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)" From="0" To="1" Duration="0:0:1" /> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </controls:ImageControl.Triggers> 
     </controls:ImageControl> 


    public class ImageControl : Image 
    { 
     public static readonly RoutedEvent SourceChangedEvent = EventManager.RegisterRoutedEvent(
     "SourceChanged", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(ImageControl)); 

     static ImageControl() 
     { 
      Image.SourceProperty.OverrideMetadata(typeof(ImageControl), new FrameworkPropertyMetadata(SourcePropertyChanged)); 
     } 

     public event RoutedEventHandler SourceChanged 
     { 
      add { AddHandler(SourceChangedEvent, value); } 
      remove { RemoveHandler(SourceChangedEvent, value); } 
     } 

     private static void SourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
     { 
      Image image = obj as Image; 
      if (image != null) 
      { 
       image.RaiseEvent(new RoutedEventArgs(SourceChangedEvent)); 
      } 
     } 
    } 
0

希望这有助于。

请单独运行此代码。

<Grid Height="200" Width="200"> 
    <Grid.Triggers> 
     <EventTrigger RoutedEvent="Loaded"> 
      <BeginStoryboard > 
       <Storyboard > 
        <ObjectAnimationUsingKeyFrames Duration="00:00:06" RepeatBehavior="Forever" Storyboard.TargetName="img1" Storyboard.TargetProperty="(Image.Source)"> 
         <DiscreteObjectKeyFrame KeyTime="00:00:00"> 
          <DiscreteObjectKeyFrame.Value> 
           <BitmapImage UriSource="image1.png" /> 
          </DiscreteObjectKeyFrame.Value> 
         </DiscreteObjectKeyFrame> 
         <DiscreteObjectKeyFrame KeyTime="00:00:02"> 
          <DiscreteObjectKeyFrame.Value> 
           <BitmapImage UriSource="image2.png" /> 
          </DiscreteObjectKeyFrame.Value> 
         </DiscreteObjectKeyFrame> 
         <DiscreteObjectKeyFrame KeyTime="00:00:04"> 
          <DiscreteObjectKeyFrame.Value> 
           <BitmapImage UriSource="image3.png" /> 
          </DiscreteObjectKeyFrame.Value> 
         </DiscreteObjectKeyFrame> 
        </ObjectAnimationUsingKeyFrames> 
        <DoubleAnimation Storyboard.TargetName="img1" RepeatBehavior="Forever" Storyboard.TargetProperty="Opacity" From="0.1" To="1" Duration="00:00:02"></DoubleAnimation> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Grid.Triggers> 
    <Image x:Name="img1" Stretch="Fill"></Image> 
</Grid> 

更新

<Storyboard FillBehavior="Stop" x:Key="FadeOut"> 
     <DoubleAnimation FillBehavior="Stop" Storyboard.TargetName="ScreensaverImage" Storyboard.TargetProperty="Opacity" From="0.05" To="1" Duration="0:0:2"> 
     </DoubleAnimation> 
    </Storyboard> 

<Storyboard FillBehavior="Stop" x:Key="FadeIn"> 
     <DoubleAnimation Storyboard.TargetName="ScreensaverImage" FillBehavior="Stop" Storyboard.TargetProperty="Opacity" From="1" To=".05" Duration="0:0:2"> 
     </DoubleAnimation> 
    </Storyboard> 

<Grid> 
    <Image x:Name="ScreensaverImage"></Image> 
</Grid> 

public partial class MainWindow : Window 
{ 

    List<Uri> savedImage = new List<Uri>(); 
    int i = 0; 
    Storyboard fadeIn, fadeOut; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Loaded += MainWindow_Loaded; 
     savedImage.Add(new Uri("image1.png", UriKind.Relative)); 
     savedImage.Add(new Uri("image2.png", UriKind.Relative)); 
     savedImage.Add(new Uri("image3.png", UriKind.Relative)); 
    } 

    void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     if (savedImage.Count > 0) 
     { 
      fadeIn = (Storyboard)this.Resources["FadeIn"]; 
      fadeOut = (Storyboard)this.Resources["FadeOut"]; 

      fadeIn.Completed += fadeIn_Completed; 
      fadeOut.Completed += fadeOut_Completed; 
      ScreensaverImage.Source = new BitmapImage(savedImage[i++]); 
      if (savedImage.Count > 1) 
      { 
       BeginStoryboard(fadeOut); 

      } 
      ScreensaverImage.Visibility = System.Windows.Visibility.Visible; 
     } 
     else 
     { 
      ScreensaverImage.Visibility = System.Windows.Visibility.Collapsed; 
     } 
    } 

    void fadeOut_Completed(object sender, EventArgs e) 
    { 
     fadeIn.Begin(); 
    } 

    void fadeIn_Completed(object sender, EventArgs e) 
    { 
     if (i == savedImage.Count) 
      i = 0; 
     ScreensaverImage.Source = new BitmapImage(savedImage[i++]); 
     fadeOut.Begin(); 
    } 



} 
+0

如果图像的数量是恒定的,那么这将起作用...我先从一个目录加载图像,然后在一定时间间隔之后一次加载一个图像。那么你能告诉我,我将如何更改相应的代码.. –

+0

请参阅答案更新。 –