WPF轮播图——DependencyProperty

来源:互联网 发布:创维50寸4k网络电视 编辑:程序博客网 时间:2024/05/20 15:41

在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


0 0
原创粉丝点击