我想创建一个图片幻灯片。为此,我在每个设定的时间间隔后在图像控制中加载了新图像。但每次我加载一个新的图像,它没有任何动画我需要加载每个图像与过渡动画或淡入淡出动画。如何在图像控制中更改图像时实现动画?以下是代码:
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 :(得分:4)
我创建了一个继承Image控件的类,其中我在图像控件的Source更改时引发了属性更改。我已经应用了触发器,现在工作正常。以下是代码:
<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));
}
}
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
您可以使用以下提供的MetroImageControl或MetroContentControl: Mahapps library for metro style