可以对绑定进行动画处理吗?

时间:2019-08-29 06:04:11

标签: c# wpf image binding

是否可以对通过绑定获得的图片进行动画处理?由于我是C#和WPF的新手,因此我尝试使用诸如绑定之类的功能。我希望旧的图片淡出(可能不透明,但这是Binding的一个选项吗?)而新的图片淡入。还是最好处理后面代码中的所有内容,我从文件夹中获取图像并将其绑定之后。

<UserControl x:Class="Screensaver.ScreensaverControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Screensaver"
             mc:Ignorable="d" DataContext="{Binding RelativeSource={RelativeSource Self}}"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Image Visibility="Visible" Source="{Binding DisplayedImagePath}" Name="Bild" Stretch="Uniform" />

    </Grid>
</UserControl>

using System;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace Screensaver
{
    /// <summary>
    /// Interaction logic for ScreensaverControl.xaml
    /// </summary>
    public partial class ScreensaverControl : UserControl
    {
        private Timer _timer;

        public ScreensaverControl()
        {
            InitializeComponent();
            this.Loaded += ScreensaverControl_Loaded;
            this.Unloaded += ScreensaverControl_Unloaded;
        }

        private void ScreensaverControl_Loaded(object sender, RoutedEventArgs e)
        {
            _timer = new Timer(OnTimer, _timer, 10, Timeout.Infinite);
        }

        private void ScreensaverControl_Unloaded(object sender, RoutedEventArgs e)
        {
            _timer.Dispose();
            _timer = null;
        }

        private int _index = -1;
        private void OnTimer(object state)
        {
            try
            {
                var files = Directory.GetFiles(@"C:\Users\mhj\source\repos\Screensaver\Fotos\", "*.png");
                if (files.Length > 0)
                {
                    _index++;
                    if (_index >= files.Length)
                        _index = 0;

                    this.Dispatcher.Invoke(() => DisplayedImagePath = files[_index]);
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if (_timer != null)
                    _timer.Change(10000, Timeout.Infinite);
            }
        }

        public string DisplayedImagePath
        {
            get { return (string)GetValue(DisplayedImagePathProperty); }
            set { SetValue(DisplayedImagePathProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DisplayedImagePath.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisplayedImagePathProperty =
            DependencyProperty.Register("DisplayedImagePath", typeof(string), typeof(ScreensaverControl), new PropertyMetadata(null));
    }

}

1 个答案:

答案 0 :(得分:0)

这是一个简单的屏幕保护程序控件的完整代码。它具有映像目录的依赖项属性。您应该为更改间隔添加另一个依赖项属性,或者为混合效果添加第二个Image。

XAML:

<UserControl x:Class="ScreenSaverControlTest.ScreenSaverControl" ...>
    <Grid>
        <Image x:Name="image1"/>
        <Image x:Name="image2"/>
    </Grid>
</UserControl>

和后面的代码:

public partial class ScreenSaverControl : UserControl
{
    public static readonly DependencyProperty ImageDirectoryProperty =
        DependencyProperty.Register(
            nameof(ImageDirectory), typeof(string), typeof(ScreenSaverControl),
            new PropertyMetadata(ImageDirectoryPropertyChanged));

    private readonly DispatcherTimer timer = new DispatcherTimer();
    private string[] imagePaths = new string[0];
    private int currentImageIndex = -1;

    public ScreenSaverControl()
    {
        InitializeComponent();

        timer.Interval = TimeSpan.FromSeconds(10);
        timer.Tick += (s, e) => NextImage();
        timer.Start();
    }

    public string ImageDirectory
    {
        get { return (string)GetValue(ImageDirectoryProperty); }
        set { SetValue(ImageDirectoryProperty, value); }
    }

    private static void ImageDirectoryPropertyChanged(
        DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var ssc = (ScreenSaverControl)o;
        var directory = (string)e.NewValue;

        if (!string.IsNullOrEmpty(directory) && Directory.Exists(directory))
        {
            ssc.imagePaths = Directory.GetFiles(directory, "*.jpg");
        }
        else
        {
            ssc.imagePaths = new string[0];
        }

        ssc.currentImageIndex = -1;
        ssc.NextImage();
    }

    private void NextImage()
    {
        if (imagePaths.Length > 0)
        {
            if (++currentImageIndex >= imagePaths.Length)
            {
                currentImageIndex = 0;
            }

            SetImage(new BitmapImage(new Uri(imagePaths[currentImageIndex])));
        }
    }

    private void SetImage(ImageSource imageSource)
    {
        var fadeOut = new DoubleAnimation(0d, TimeSpan.FromSeconds(1));
        var fadeIn = new DoubleAnimation(1d, TimeSpan.FromSeconds(1));
        var newImage = image1;
        var oldImage = image2;

        if (image1.Source != null)
        {
            newImage = image2;
            oldImage = image1;
        }

        fadeOut.Completed += (s, e) => oldImage.Source = null;

        oldImage.BeginAnimation(OpacityProperty, fadeOut);
        newImage.BeginAnimation(OpacityProperty, fadeIn);
        newImage.Source = imageSource;
    }
}

像这样使用它:

<local:ScreenSaverControl ImageDirectory="C:\Users\Public\Pictures\Sample Pictures"/>