控件代码已经更新,支持上下左右四个方向。VS2010工程

/Files/RMay/WPF_Marquee/WpfMarquee.zip

我们知道在html中有一个marquee标签,可以很方便的实现文字滚动的效果,比如如下简单的声明:

<marquee loop="3" behavior="scroll">文本信息<marquee>

在WPF里面,当然,我们可以用Animation和Storyboard来达到同样的效果,但是感觉总是不那么好,每次都需要做动画。而且设置动画的属性很麻烦。能不能就像HTML简单的声明就行了呢?比如:

<l:Marquee Content="123" Direction="Right" Behavior="Scroll" ScrollAmount="20" ScrollDelay="500"/>

能够这样简单的指定属性来使用。

下面我们就用开发CustomControl的方式来打造一个Marquee控件。

首先,我们添加一个自定义控件,这个控件继承自ContentControl,因为它的里面可以放任何东西,而不仅仅限于文本。

接着,仿造html中的marquee标签,定义一些必要的属性。这些属性都是DependencyProperty。

接下来我们需要写动画的逻辑了。有三种方式来写这个动画:

1、利用系统的Animation和Storyboard

2、在CompositionTarget的Rendering事件中写动画

3、利用DispatcherTimer写动画

我们这儿动画的行为有好几种,比较复杂,利用系统的动画方式来写会很麻烦,并且这儿有一个ScrollDelay属性来控制延时,在CompositionTarget的Rendering事件中不太好控制,因此,最后我选择用DispatcherTimer,在它的Tick事件中写动画逻辑。

动画的逻辑主要就是改变Content的位移,需要注意的是,这个位移是通过TranlateTransform来实现的。

部分代码如下:

Code
protected virtual void OnUpdateContentPosition()
        {
            if (_contentHost != null)
            {
                double contentWidth = _contentHost.DesiredSize.Width;
                double leftBound = 0.0, rightBound = 0.0;

// Alternate不飞出边界
                if (this.Behavior == MarqueeBehavior.Alternate || this.Behavior == MarqueeBehavior.Slide)
                {
                    leftBound = 0;
                    rightBound = this.ActualWidth - contentWidth;
                }
                // Scroll要飞出边界
                else if (this.Behavior == MarqueeBehavior.Scroll)
                {
                    leftBound = -contentWidth;
                    rightBound = this.ActualWidth;
                }

// 循环次数的计数
                if (_currentLoop < this.Loop)
                {
                    // 计算位移
                    // 这里逻辑比较重复,可以考虑合并
                    if (_currentDirection == Direction.Left)
                    {
                        _contentTranlate.X -= this.ScrollAmount;

// 从右往左到头了
                        if (_contentTranlate.X <= leftBound)
                        {
                            if (this.Behavior == MarqueeBehavior.Scroll || this.Behavior == MarqueeBehavior.Slide)
                            {
                                _contentTranlate.X = rightBound;
                            }
                            else if (this.Behavior == MarqueeBehavior.Alternate)
                            {
                                _currentDirection = Direction.Right;
                            }
                            _currentLoop += _loopCounter;
                        }
                    }
                    else if (_currentDirection == Direction.Right)
                    {
                        _contentTranlate.X += this.ScrollAmount;
                        // 从左往右到头了
                        if (_contentTranlate.X >= rightBound)
                        {
                            if (this.Behavior == MarqueeBehavior.Scroll || this.Behavior == MarqueeBehavior.Slide)
                            {
                                _contentTranlate.X = leftBound;

}
                            else if (this.Behavior == MarqueeBehavior.Alternate)
                            {
                                _currentDirection = Direction.Left;
                            }
                            _currentLoop += _loopCounter;
                        }
                    }
                }// End of Loop
                else
                {
                    // 保证动画结束后可见
                    if (_contentTranlate.X < 0)
                    {
                        _contentTranlate.X = 0;
                    }
                    if (_contentTranlate.X > this.ActualWidth - contentWidth)
                    {
                        _contentTranlate.X = this.ActualWidth - contentWidth;
                    }
                }
            }
        }

更详尽的内容可以直接参看源码。

使用的时候非常简单

Code
            <!--文字可以-->
            <l:Marquee Content="123" Direction="Right" Behavior="Scroll" ScrollAmount="20" ScrollDelay="500"/>
            <!--图形也可以-->
            <l:Marquee Direction="Right" Behavior="Slide">
                <Rectangle Width="20" Height="20" Fill="Blue"/>
            </l:Marquee>
            <!--控件也没有问题-->
            <l:Marquee>
                <Button Content="Button" Width="50"/>
            </l:Marquee>

需要注意的是,如果设定了Loop,当Loop结束的时候,我并没有停止Timer,这样在Window Resize之后动画会重新播放。读者可以将选择其Stop掉,而在ResetAnimation方法中重新启动。

源码下载:

/Files/RMay/WPF_Marquee/WpfMarquee.rar

转载于:https://www.cnblogs.com/RMay/archive/2009/01/20/1379023.html

【WPF】用CustomControl打造WPF版的Marquee相关推荐

  1. WPF 自定义 MessageBox (相对完善版 v1.0.0.6)

    基于WPF的自定义 MessageBox. 众所周知WPF界面美观.大多数WPF元素都可以简单的修改其样式,从而达到程序的风格统一.可是当你不得不弹出一个消息框通知用户消息时(虽然很不建议在程序中频繁 ...

  2. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为"样式",在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外 ...

  3. 打造精简版Linux-mini

    Linux系统的核心就是它的内核,所有的Linux系统采用的内核都是相同的,唯一不同的就是除了内核以外的服务以及应用的软件不同而已.那麽可以根据Linux的这一特点,我们可以根据自己的需求打造属于自己 ...

  4. 【WPF】如何使用wpf实现屏幕最前端的绘图?

    [WPF]如何使用wpf实现屏幕最前端的绘图? 原文:[WPF]如何使用wpf实现屏幕最前端的绘图? 引言 在知乎上面看到如何使用wpf实现屏幕最前端的绘图? 这么一个问题,觉得全屏弹幕很有趣,所以把 ...

  5. WPF笔记(1.1 WPF基础)——Hello,WPF!

    WPF笔记(1.1 WPF基础)--Hello,WPF! 原文:WPF笔记(1.1 WPF基础)--Hello,WPF! Example 1-1. Minimal C# WPF application ...

  6. Binding是WPF的核心,WPF的常用数据源绑定有四种

    Binding是WPF的核心,WPF的数据源有以下几种: 1.ADO.NET中的DataTable 2.xml数据源 3.object数据源 4.元素控件属性 详细说明见链接:http://www.c ...

  7. [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)

    [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu) 原文 [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu) [WPF疑难]如何禁用WPF窗口的系统菜单(SystemM ...

  8. 24小时极限挑战WPF:LOLVoiceExtractor(WPF/C++DLL)实战--(图片修复,增加程序包)

    24小时极限挑战WPF:LOLVoiceExtractor(WPF/C++DLL)实战 --Zephyroal 楔子: 游戏入迷太多终究不是件好事,技术同样有趣,可千万不能荒废,在每日闲余撸一把的时候 ...

  9. WPF入门0:WPF的基础知识

    WPF入门0:WPF的基础知识 WPF 可创建动态的数据驱动的呈现系统. 系统的每一部分均可通过驱动行为的属性集来创建对象. 数据绑定是系统的基础部分,在每一层中均进行了集成. 传统的应用程序创建一个 ...

最新文章

  1. 手摸手产品研究院 | 玲珑沙龙-一个可以“撕逼”的女性文化社区
  2. java.io.EOFException: Chunk stream does not exist at page: 0
  3. 红黑树与平衡二叉树_百图详解红黑树,想不理解都难
  4. opencv调节图片饱和度_OpenCV调整彩色图像的饱和度和亮度
  5. 谷歌推出TFGAN:开源的轻量级生成对抗网络库
  6. php ecdsa secp256k1,从上的压缩派生ECDSA未压缩公钥
  7. [K/3Cloud]创建一个操作校验器
  8. 【软考 系统架构设计师】软件架构设计④ 基于架构的软件开发方法
  9. php与sap系统,sap系统是什么系统
  10. 《程序员之禅》一一1.1 我如何学习打坐
  11. 色彩搭配原则和方法【转】
  12. <C++>运算符重载进阶之左移运算符,输出成员属性一步到位
  13. 37-递归求第五个人的年龄
  14. 关于不同操作系统下浏览器兼容问题
  15. C语言是一个什么样的语言
  16. 暑期训练day14 A. XXXXX
  17. Opencv 笔记7 凸包算法-Graham扫描法
  18. Mandriva 2009 Spring PWP中3D桌面的使用
  19. 京东商城ContainerLB实践
  20. 如何成为高效的学习高手

热门文章

  1. Framework 源码解析知识梳理(5) startService 源码分析
  2. 分布式架构中异步的使用场景
  3. Spring 4 使用Freemarker模板发送邮件添加附件
  4. 说说大型高并发高负载网站的系统架构(更新)
  5. SQLServer 一些有用的语句
  6. GSL库在VC6.0上的配置
  7. android程序排序算法实现
  8. 阿里云移动端播放器高级功能---直播时移
  9. china-pub计算机图书最新一周排行榜
  10. 与女儿谈商业模式 (3):沃尔玛的成功模式