【问题标题】:Animate Image when loaded in Image Control在图像控件中加载时动画图像
【发布时间】:2014-05-31 05:40:00
【问题描述】:

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

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();
    }
}

【问题讨论】:

  • 但是我将如何为新图像的变化制作动画?意味着它应该看起来像加载了动画的新图像。
  • 你可以有两个重叠的图像。淡入顶部图像,设置底部图像,淡出顶部图像,设置顶部图像,重复。 this 也可能会有所帮助。
  • 我不能创建一些在图像源更改时触发的触发器吗?

标签: c# wpf image xaml animation


【解决方案1】:

希望这会有所帮助。

请单独运行此代码。

<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】:

您可以使用以下提供的 MetroImageControl 或 MetroContentControl: Mahapps library for metro style

【讨论】:

    【解决方案3】:

    我创建了一个继承图像控件的类,当图像控件的源发生更改时,我在其中引发了属性更改。我在其上应用了触发器,现在可以正常工作。以下是代码:

    <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));
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2011-11-10
      • 2012-08-20
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 2013-05-13
      • 1970-01-01
      • 2016-03-31
      • 2016-05-24
      相关资源
      最近更新 更多