WPF轮播图——DependencyProperty

在WPF实现轮播图,本例使用了用户自定义控件,并设置了DependencyProperty属性以方便做设置,以下是详细步骤:

1.新建WPF项目,新建一个UserControl用户控件用作我们的轮播图控件(本例:PrintS/UC/RollImg.xaml):

xaml:

<UserControl x:Class="PrintS.UC.RollImg"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="900" d:DesignWidth="900">
    <Grid>
        <Canvas Name="canvas_board" ClipToBounds="True"
            Height="900" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="900">

            <Image Name="image1" Opacity="1.0"
                Canvas.Left="0" Canvas.Top="0" Height="900" Stretch="Fill" Width="900" />

            <Image Name="image2" Opacity="1.0"
                Canvas.Left="0" Canvas.Top="0" Height="900" Stretch="Fill" Width="900" />

        </Canvas>
    </Grid>
</UserControl>
xaml.cs:

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.Navigation;
using System.Windows.Shapes;

using System.Windows.Media.Animation;

namespace PrintS.UC
{
    /// <summary>
    /// RollImg.xaml 的交互逻辑
    /// </summary>
    public partial class RollImg : UserControl
    {
        public RollImg()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 动画静止时间
        /// </summary>
        public double TimeHold
        {
            get { return (double)GetValue(TimeHoldProperty); }
            set { SetValue(TimeHoldProperty, value); }
        }
        public static readonly DependencyProperty TimeHoldProperty =
            DependencyProperty.Register("TimeHold", typeof(double), // 注册属性名
            typeof(RollImg),    // 所属控件
            new PropertyMetadata(5.0) // 默认值
            );

        /// <summary>
        /// 动画播放时间
        /// </summary>
        public double TimeChange
        {
            get { return (double)GetValue(TimeChangeProperty); }
            set { SetValue(TimeChangeProperty, value); }
        }
        public static readonly DependencyProperty TimeChangeProperty =
            DependencyProperty.Register("TimeChange", typeof(double), // 注册属性名
            typeof(RollImg),    // 所属控件
            new PropertyMetadata(3.0) // 默认值
            );

        // 枚举动画类型
        public enum StoryTypes
        {
            /// <summary>
            /// 从右向左
            /// </summary>
            RightToLeft = 1,
            /// <summary>
            /// 从左向右
            /// </summary>
            LeftToRight,
            /// <summary>
            /// 从上向下
            /// </summary>
            TopToBottom,
            /// <summary>
            /// 从下向上
            /// </summary>
            BottomToTop,
            /// <summary>
            /// 不透明度
            /// </summary>
            Opacity
        }
        /// <summary>
        /// 动画类型
        /// </summary>
        public StoryTypes StoryType
        {
            get { return (StoryTypes)GetValue(StoryTypeProperty); }
            set { SetValue(StoryTypeProperty, value); }
        }
        /// <summary>
        /// 在xaml中操作属性,需要声明为DependencyProperty
        /// </summary>
        public static readonly DependencyProperty StoryTypeProperty =
            DependencyProperty.Register("StoryType", typeof(StoryTypes),
            typeof(RollImg),
            new PropertyMetadata(StoryTypes.LeftToRight)
            );

        /// <summary>
        /// 是否开始滚动
        /// </summary>
        public bool isBegin = false;

        /// <summary>
        /// 本轮剩余滚动数
        /// </summary>
        public int rollNum = 0;

        private List<BitmapImage> _ls_images;
        /// <summary>
        /// 滚动图片组
        /// </summary>
        public List<BitmapImage> ls_images
        {
            set
            {
                if (rollNum > 0)
                {
                    // 本轮滚动未结束
                }
                else
                {
                    // 开始新的一轮滚动
                    _ls_images = value;
                    rollNum = _ls_images.Count();
                }
            }
            get { return _ls_images; }
        }

        /// <summary>
        /// 滚动宽度
        /// </summary>
        public double width
        {
            get { return this.canvas_board.Width; }
        }

        /// <summary>
        /// 滚动高度
        /// </summary>
        public double height
        {
            get { return this.canvas_board.Height; }
        }

        private int n_index = 0;    // 滚动索引

        private Storyboard _storyboard_RightToLeft;
        /// <summary>
        /// 滚动动画板,从右到左
        /// </summary>
        public Storyboard storyboard_RightToLeft
        {
            get
            {
                if (_storyboard_RightToLeft == null)
                {
                    _storyboard_RightToLeft = new Storyboard();

                    _storyboard_RightToLeft.Children.Add(
                        this.getDAUKF(0.0, -this.width, this.image1, new PropertyPath("(Canvas.Left)"))
                        );

                    _storyboard_RightToLeft.Children.Add(
                        this.getDAUKF(this.width, 0.0, this.image2, new PropertyPath("(Canvas.Left)"))
                        );

                    _storyboard_RightToLeft.FillBehavior = FillBehavior.Stop;
                    _storyboard_RightToLeft.Completed += new EventHandler(storyboard_Completed);
                }
                return _storyboard_RightToLeft;
            }
        }

        private Storyboard _storyboard_LeftToRight;
        /// <summary>
        /// 滚动动画板,从左到右
        /// </summary>
        public Storyboard storyboard_LeftToRight
        {
            get
            {
                if (_storyboard_LeftToRight == null)
                {
                    _storyboard_LeftToRight = new Storyboard();

                    _storyboard_LeftToRight.Children.Add(
                        this.getDAUKF(0.0, this.width, this.image1, new PropertyPath("(Canvas.Left)"))
                        );

                    _storyboard_LeftToRight.Children.Add(
                        this.getDAUKF(-this.width, 0.0, this.image2, new PropertyPath("(Canvas.Left)"))
                        );

                    _storyboard_LeftToRight.FillBehavior = FillBehavior.Stop;
                    _storyboard_LeftToRight.Completed += new EventHandler(storyboard_Completed);
                }
                return _storyboard_LeftToRight;
            }
        }

        private Storyboard _storyboard_TopToBottom;
        /// <summary>
        /// 滚动动画板,从上到下
        /// </summary>
        public Storyboard storyboard_TopToBottom
        {
            get
            {
                if (_storyboard_TopToBottom == null)
                {
                    _storyboard_TopToBottom = new Storyboard();

                    _storyboard_TopToBottom.Children.Add(
                        this.getDAUKF(0.0, this.height, this.image1, new PropertyPath("(Canvas.Top)"))
                        );

                    _storyboard_TopToBottom.Children.Add(
                        this.getDAUKF(-this.height, 0.0, this.image2, new PropertyPath("(Canvas.Top)"))
                        );

                    _storyboard_TopToBottom.FillBehavior = FillBehavior.Stop;
                    _storyboard_TopToBottom.Completed += new EventHandler(storyboard_Completed);
                }
                return _storyboard_TopToBottom;
            }
        }

        private Storyboard _storyboard_BottomToTop;
        /// <summary>
        /// 滚动动画板,从下到上
        /// </summary>
        public Storyboard storyboard_BottomToTop
        {
            get
            {
                if (_storyboard_BottomToTop == null)
                {
                    _storyboard_BottomToTop = new Storyboard();

                    _storyboard_BottomToTop.Children.Add(
                        this.getDAUKF(0.0, -this.height, this.image1, new PropertyPath("(Canvas.Top)"))
                        );

                    _storyboard_BottomToTop.Children.Add(
                        this.getDAUKF(this.height, 0.0, this.image2, new PropertyPath("(Canvas.Top)"))
                        );

                    _storyboard_BottomToTop.FillBehavior = FillBehavior.Stop;
                    _storyboard_BottomToTop.Completed += new EventHandler(storyboard_Completed);
                }
                return _storyboard_BottomToTop;
            }
        }

        private Storyboard _storyboard_Opacity;
        /// <summary>
        /// 滚动动画板,渐现
        /// </summary>
        public Storyboard storyboard_Opacity
        {
            get
            {
                if (_storyboard_Opacity == null)
                {
                    _storyboard_Opacity = new Storyboard();

                    _storyboard_Opacity.Children.Add(
                        this.getDAUKF(0.0, 1.0, this.image2, new PropertyPath("(Image.Opacity)"))
                        );

                    _storyboard_Opacity.FillBehavior = FillBehavior.Stop;
                    _storyboard_Opacity.Completed += new EventHandler(storyboard_Completed);
                }
                return _storyboard_Opacity;
            }
        }

        /// <summary>
        /// 获取动画中Double类型属性的关键帧组
        /// </summary>
        /// <param name="from">初始值</param>
        /// <param name="to">目标值</param>
        /// <param name="obj">动画控件</param>
        /// <param name="path">动画属性</param>
        /// <returns>关键帧组</returns>
        DoubleAnimationUsingKeyFrames getDAUKF(double from, double to, DependencyObject obj, PropertyPath path)
        {
            DoubleAnimationUsingKeyFrames daukf = new DoubleAnimationUsingKeyFrames();
            LinearDoubleKeyFrame k1 = new LinearDoubleKeyFrame(from, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(this.TimeHold)));
            LinearDoubleKeyFrame k2 = new LinearDoubleKeyFrame(to, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(this.TimeHold + this.TimeChange)));
            daukf.KeyFrames.Add(k1);
            daukf.KeyFrames.Add(k2);
            Storyboard.SetTarget(daukf, obj);
            Storyboard.SetTargetProperty(daukf, path);
            return daukf;
        }

        // 动画结束时
        void storyboard_Completed(object sender, EventArgs e)
        {
            rollNum--;

            // 显示图片
            this.ResetStory();

            // 继续下轮动画
            this.BeginStoty();
        }

        /// <summary>
        /// 开始滚动动画
        /// </summary>
        public void Begin()
        {
            if (!isBegin)
            {
                isBegin = true;

                // 显示图片
                this.ResetStory();

                // 开始动画
                this.BeginStoty();
            }
        }

        /// <summary>
        /// 开始播放动画
        /// </summary>
        void BeginStoty()
        {
            switch (this.StoryType)
            {
                case StoryTypes.LeftToRight:
                    this.storyboard_LeftToRight.Begin();
                    break;
                case StoryTypes.TopToBottom:
                    this.storyboard_TopToBottom.Begin();
                    break;
                case StoryTypes.BottomToTop:
                    this.storyboard_BottomToTop.Begin();
                    break;
                case StoryTypes.Opacity:
                    this.storyboard_Opacity.Begin();
                    break;
                default:
                    this.storyboard_RightToLeft.Begin();
                    break;
            }
        }

        /// <summary>
        /// 初始化动画版,显示动画中的图片
        /// </summary>
        void ResetStory()
        {
            // 图片复位
            switch (this.StoryType)
            {
                case StoryTypes.LeftToRight:
                    this.image1.SetValue(Canvas.LeftProperty, 0.0);
                    this.image2.SetValue(Canvas.LeftProperty, -this.width);
                    break;
                case StoryTypes.TopToBottom:
                    this.image1.SetValue(Canvas.TopProperty, 0.0);
                    this.image2.SetValue(Canvas.TopProperty, -this.height);
                    break;
                case StoryTypes.BottomToTop:
                    this.image1.SetValue(Canvas.TopProperty, 0.0);
                    this.image2.SetValue(Canvas.TopProperty, this.height);
                    break;
                case StoryTypes.Opacity:
                    this.image2.SetValue(Image.OpacityProperty, 0.0);
                    break;
                default:
                    this.image1.SetValue(Canvas.LeftProperty, 0.0);
                    this.image2.SetValue(Canvas.LeftProperty, this.width);
                    break;
            }

            // 显示图片
            if (this.ls_images.Count > 0)
            {
                try
                {
                    this.image1.Source = this.ls_images[this.n_index++ % this.ls_images.Count];
                    this.image2.Source = this.ls_images[this.n_index % this.ls_images.Count];
                }
                catch (Exception ex)
                {
                    this.image1.Source = new BitmapImage();
                    this.image2.Source = new BitmapImage();
                }
            }
            else
            {
                this.image1.Source = new BitmapImage();
                this.image2.Source = new BitmapImage();
            }
        }
    }
}
2.在主窗口中使用轮播图控件:

<Window x:Class="PrintS.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:uc="clr-namespace:PrintS.UC"
        Title="PrintS" Height="900" Width="1440" 
        Loaded="Window_Loaded" WindowState="Maximized" WindowStyle="None">
    <Grid>

        <uc:RollImg x:Name="rollImg" StoryType="Opacity" TimeHold="3" TimeChange="2"
            Height="900" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="900" />

    </Grid>
</Window>
因为我们的轮播图控件中,声明了StoryType、TimeHold、TimeChange的属性(DependencyProperty),可以很方便地在主窗口的xaml中进行设置

部分代码此处省略,可参考简化版:http://blog.csdn.net/xwlyun/article/details/41477385


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值