WPF轮播图——UserControl

本文介绍了一种在WPF应用程序中实现轮播图的方法,通过创建自定义UserControl控件来封装轮播逻辑,利用Storyboard动画实现平滑过渡效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在WPF中实现轮播图的方法有很多,本例将采用UserControl用户自定义控件的方式进行封装,以下是具体实现步骤:

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"
                Canvas.Left="0" Canvas.Top="0" Height="900" Stretch="Fill" Width="900" />

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

        </Canvas>
    </Grid>
</UserControl>
使用一个canvas,两个image用来绘制轮播图动画

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 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_R2L;
        /// <summary>
        /// 滚动动画板
        /// </summary>
        public Storyboard storyboard_R2L
        {
            get
            {
                if (_storyboard_R2L == null)
                {
                    _storyboard_R2L = new Storyboard();
                    DoubleAnimationUsingKeyFrames daukf_img1 = new DoubleAnimationUsingKeyFrames();
                    LinearDoubleKeyFrame k1_img1 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5)));
                    LinearDoubleKeyFrame k2_img1 = new LinearDoubleKeyFrame(-this.width, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(8)));
                    daukf_img1.KeyFrames.Add(k1_img1);
                    daukf_img1.KeyFrames.Add(k2_img1);
                    _storyboard_R2L.Children.Add(daukf_img1);
                    Storyboard.SetTarget(daukf_img1, this.image1);
                    Storyboard.SetTargetProperty(daukf_img1, new PropertyPath("(Canvas.Left)"));

                    DoubleAnimationUsingKeyFrames daukf_img2 = new DoubleAnimationUsingKeyFrames();
                    LinearDoubleKeyFrame k1_img2 = new LinearDoubleKeyFrame(this.width, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(5)));
                    LinearDoubleKeyFrame k2_img2 = new LinearDoubleKeyFrame(0.0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(8)));
                    daukf_img2.KeyFrames.Add(k1_img2);
                    daukf_img2.KeyFrames.Add(k2_img2);
                    _storyboard_R2L.Children.Add(daukf_img2);
                    Storyboard.SetTarget(daukf_img2, this.image2);
                    Storyboard.SetTargetProperty(daukf_img2, new PropertyPath("(Canvas.Left)"));

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

        void storyboard_Completed(object sender, EventArgs e)
        {
            rollNum--;

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

            // 继续下轮动画
            storyboard_R2L.Begin();
        }

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

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

                // 开始动画
                storyboard_R2L.Begin();
            }
        }

        /// <summary>
        /// 初始化动画版,显示动画中的图片
        /// </summary>
        void ResetStory()
        {
            // 复位
            this.image1.SetValue(Canvas.LeftProperty, 0.0);
            this.image2.SetValue(Canvas.LeftProperty, this.width);
            // 显示图片
            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.在主窗口中,引用自定义控件:

MainWindow.xaml:

<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" 
        WindowState="Maximized" WindowStyle="None">
    <Grid Background="#e2efe1">
        <uc:RollImg x:Name="rollImg"
            Height="900" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="900" />
    </Grid>
</Window>
需要添加自定义控件所在的命名空间:xmlns:uc="clr-namespace:PrintS.UC"

使用时:<uc:RollImg .... />

MainWindow.xaml.cs:

            List<BitmapImage> ls_adv_img = new List<BitmapImage>();

            // 根据自己的业务逻辑进行赋值操作
            foreach (Adv a in listAdv)
            {
                BitmapImage img;
                try
                {
                    img = new BitmapImage(new Uri(string.Format(@"{0}\{1}", pathAdv, a.pic)));
                }
                catch (Exception ex)
                {
                    img = new BitmapImage();
                }
                ls_adv_img.Add(img);
            }

            this.rollImg.ls_images = ls_adv_img;

            this.rollImg.Begin();


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值