前    注:

这是自己平时根据自己需要写的一些小代码,未必对各看官有用。另外,这是根据个人想法而写,未必严谨和符合设计原则,若有任何不妥之处,还请不吝赐教。

说    明:

本文描述一个可滚动显示文本信息的状态栏标签控件。起因是某天领导说某些信息应该更醒目,让用户更容易注意到。于是就花了半天的时间做了这个东西。

基本的思路是用定时器每隔一段时间重绘文本,使其显示在控件的不同位置。

已经实现了关于滚动速度、精细度的控制功能,已经实现由右至左滚动显示的滚动方式。

使用方式:将向状态栏添加标签,再到设计器代码中将标签类型改为ToolStripStatusRollingLabel。

设计要点:

1、由于ToolStripStatusLabel无法设置文本的显示位置,因此需要重载OnPaint来更改文本的绘制逻辑。为了避免完全重绘控件,重写的OnPaint函数先调用ToolStripStatusLabel.OnPaint,再使用GDI在控件上绘制文本。

为了提供与ToolStripStatusLabel类似的使用接口,保留Text作为新控件中设置需滚动显示的文本内容的属性。由于ToolStripStatusLabel.OnPaint同样会绘制文本,若不特殊处理,控件将会同时显示一个滚动的文本和一个静止的文本。

因此,需要重载Text属性,将需要显示的文本内容另设变量存储(用于在重写的OnPaint中使用),并且使Text属性在运行时为空。另一方面,为保证用户体验,又需要Text属性在设计器中的值与所设置的值一致。这就是重写的Text属性的get访问器需要判断DesignMode的原因。

2、滚动的速度与精细度通过两个属性组合来控制:一、RollSpeed,设置定时器每次动作时,文本显示位置与上一次显示位置之间的距离;二、RedrawTimeSpan,设置定时器触发的时间间隔。RedrawTimeSpan越小,RoolSpeed越大,滚动的速度越快;RedrawTimeSpan越小,RoolSpeed越小,滚动的精细度越高。

3、控件的滚动样式由文本在控件上的显示位置的变化规律决定。便于扩展滚动样式,计算文本显示位置的逻辑被抽取出来,形成一个单独的接口IControlDataRollOffsetGenerater。

4、IControlDataRollOffsetGenerater提供获取一个在某个区间内滚动的数值的接口。对我能想到的所有滚动样式,文本的每个显示位置均可由控件宽度、文本宽度及上次显示位置和每次的偏移量确定。在此接口中,这些数据分别由WindowWidth、DataWidth、Offset和Speed表示。

5、特殊的滚动效果:文本朝某个方向滚动,消失的部分文本从控件的另一端显示出来。可以这样实现:将用户要显示的文本用空白拼接起来显示,空白的长度等于控件宽度与文本长度的差。当然,这要求文本长度不能超过控件宽度。

结构图  :

源代码  :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace CommonLibrary.ExtendedControl
{/// <summary>/// 滚动显示的状态栏标签类/// </summary>public class ToolStripStatusRollingLabel : ToolStripStatusLabel{public ToolStripStatusRollingLabel(){StringRect.X = this.Padding.Left;StringRect.Y = this.Padding.Top;StringRect.Height = Size.Height - Padding.Top - Padding.Bottom;Brush = new SolidBrush(this.ForeColor);ControlDataRollOffsetGenerater = ControlDataRollOffsetGeneraterFactory.Instance.GetControlDataRollOffsetGenerater(this.RollSytle,0,0,3,0);this.UpdateTimer = new Timer();this.UpdateTimer.Interval = 500;this.UpdateTimer.Enabled = true;this.UpdateTimer.Tick += delegate { this.OnTick(); };}#region 辅助/// <summary>/// 定时器/// </summary>private Timer UpdateTimer;/// <summary>/// 笔刷/// </summary>SolidBrush Brush;/// <summary>/// 用于显示内容的矩形/// </summary>Rectangle StringRect = Rectangle.Empty;/// <summary>/// 滚动的偏移量生成器/// </summary>IControlDataRollOffsetGenerater ControlDataRollOffsetGenerater;/// <summary>/// 图形/// </summary>Graphics Graphics;#endregion#region 数据/// <summary>/// 显示内容/// </summary>private string _Text;/// <summary>/// 滚动距离/// </summary>private int _RollDistance = 0;/// <summary>/// 控件内容的滚动样式/// </summary>private EnumTextRollStyle _RollStyle = EnumTextRollStyle.TurnLeft;/// <summary>/// 文本宽度/// </summary>private int _TextWidth;#endregion#region 属性/// <summary>/// 文本内容/// </summary>public override string Text{get{if (DesignMode){return _Text;}else{return string.Empty;}}set{if (_Text == value) return;_Text = value;if (!DesignMode){if (Graphics != null) TextWidth = (int)(Graphics.MeasureString(value, this.Font).Width);this.Invalidate();}}}/// <summary>/// 文本宽度/// </summary>public int TextWidth{get { return _TextWidth; }set{if (_TextWidth == value) return;_TextWidth = value;if (ControlDataRollOffsetGenerater != null) ControlDataRollOffsetGenerater.DataWidth = value;}}/// <summary>/// 前景色/// </summary>public override Color ForeColor{get{return base.ForeColor;}set{Brush = new SolidBrush(base.ForeColor);base.ForeColor = value;//this.Invalidate();}}/// <summary>/// 控件大小/// </summary>public override Size Size{get{return base.Size;}set{if (this.Size == value) return;base.Size = value;StringRect.Height = Size.Height - Padding.Top - Padding.Bottom;if (ControlDataRollOffsetGenerater != null) ControlDataRollOffsetGenerater.WindowWidth = this.Size.Width - Padding.Left - Padding.Right;}}/// <summary>/// 内部间距/// </summary>public override Padding Padding{get{return base.Padding;}set{if (value == Padding) return;base.Padding = value;StringRect.Y = Padding.Top;StringRect.Height = Size.Height - Padding.Top - Padding.Bottom;if (ControlDataRollOffsetGenerater != null) ControlDataRollOffsetGenerater.WindowWidth = this.Size.Width - Padding.Left - Padding.Right;}}/// <summary>/// 滚动速度/// </summary>public int RedrawTimeSpan{get { return UpdateTimer.Interval; }set{UpdateTimer.Interval = value;}}/// <summary>/// 滚动速度:每次刷新文本显示位置的间距/// </summary>public int RoolSpeed{get{return ControlDataRollOffsetGenerater.Speed;}set{ControlDataRollOffsetGenerater.Speed = value;}}/// <summary>/// 当前显示位置与初始位置的距离/// </summary>public int RollDistance{get { return _RollDistance; }set { _RollDistance = value; }}/// <summary>/// 控件内容的滚动样式/// </summary>public EnumTextRollStyle RollSytle{get { return _RollStyle; }set{if (_RollStyle == value) return;_RollStyle = value;ControlDataRollOffsetGenerater = ControlDataRollOffsetGeneraterFactory.Instance.GetControlDataRollOffsetGenerater(value, StringRect.Width, TextWidth, this.RedrawTimeSpan, this.RollDistance);}}#endregionprivate void OnTick(){//if (ControlDataRollOffsetGenerater == null) return;RollDistance = ControlDataRollOffsetGenerater.GetNextOffset();StringRect.X = this.Padding.Left + RollDistance;StringRect.Width = ControlDataRollOffsetGenerater.WindowWidth - RollDistance;this.Invalidate();}protected override void OnPaint(PaintEventArgs e){if (Graphics == null){Graphics = e.Graphics;TextWidth = (int)(Graphics.MeasureString(_Text, this.Font).Width);}e.Graphics.DrawString(_Text, this.Font, Brush, StringRect);base.OnPaint(e);}}/// <summary>/// 控件文本内容滚动的样式/// </summary>public enum EnumTextRollStyle{/// <summary>/// 向左滚动/// </summary>TurnLeft,/// <summary>/// 向左滚动/// </summary>TurnRight,/// <summary>/// 来回滚动/// </summary>PingPong}public class ControlDataRollOffsetGeneraterFactory{#region 单例static Singleton<ControlDataRollOffsetGeneraterFactory> Singleton;public static ControlDataRollOffsetGeneraterFactory Instance{get{if (Singleton == null) Singleton = new Singleton<ControlDataRollOffsetGeneraterFactory>();return Singleton.Instance;}}#endregion/// <summary>/// 获取一个数据滚动的偏移量生成器/// </summary>/// <param name="RollStyle"></param>/// <param name="WindowWidth"></param>/// <param name="DataWidth"></param>/// <param name="Speed"></param>/// <param name="InitOffset"></param>/// <returns></returns>public IControlDataRollOffsetGenerater GetControlDataRollOffsetGenerater(EnumTextRollStyle RollStyle, int WindowWidth, int DataWidth, int Speed, int InitOffset){switch (RollStyle){case EnumTextRollStyle.TurnLeft:return new ControlDataRollToLeftOffsetGenerater(WindowWidth, DataWidth, Speed, InitOffset);}return null;}}/// <summary>/// 控件内容滚动偏移量生成器的接口/// </summary>public interface IControlDataRollOffsetGenerater{/// <summary>/// 显示区域宽度/// </summary>int WindowWidth { get;set;}/// <summary>/// 数据宽度/// </summary>int DataWidth { get;set;}/// <summary>/// 偏移量/// </summary>int Offset { get;set;}/// <summary>/// 移动速度/// </summary>int Speed { get;set;}/// <summary>/// 获取下一个偏移量/// </summary>/// <returns>新偏移量</returns>int GetNextOffset();}/// <summary>/// 控件内容滚动偏移量生成器基类/// </summary>public class ControlDataRollOffsetGeneraterBase : IControlDataRollOffsetGenerater{public ControlDataRollOffsetGeneraterBase(){}public ControlDataRollOffsetGeneraterBase(int WindowWidth, int DataWidth, int Speed){this._WindowWidth = WindowWidth;this._DataWidth = DataWidth;this._Speed = Speed;}public ControlDataRollOffsetGeneraterBase(int WindowWidth, int DataWidth, int Speed, int InitOffset){this._WindowWidth = WindowWidth;this._DataWidth = DataWidth;this._Speed = Speed;this._Offset = InitOffset;}#region 数据/// <summary>/// 显示区域宽度/// </summary>int _WindowWidth;/// <summary>/// 数据宽度/// </summary>int _DataWidth;/// <summary>/// 偏移量/// </summary>int _Offset;/// <summary>/// 移动速度/// </summary>int _Speed;#endregion#region 属性/// <summary>/// 显示区域宽度/// </summary>public virtual int WindowWidth{get{return _WindowWidth;}set{_WindowWidth = value;}}/// <summary>/// 数据宽度/// </summary>public virtual int DataWidth{get{return _DataWidth;}set{_DataWidth = value;}}/// <summary>/// 偏移量/// </summary>public virtual int Offset{get{return _Offset;}set{_Offset = value;}}/// <summary>/// 移动速度/// </summary>public virtual int Speed{get{return _Speed;}set{_Speed = value;}}#endregion/// <summary>/// 获取下一个偏移量/// </summary>/// <returns>新偏移量</returns>public virtual int GetNextOffset(){return 0;}}/// <summary>/// 控件内容向左滚动的偏移量生成器/// </summary>public class ControlDataRollToLeftOffsetGenerater : ControlDataRollOffsetGeneraterBase{public ControlDataRollToLeftOffsetGenerater(int WindowWidth, int DataWidth, int Speed): base(WindowWidth, DataWidth, Speed){//RollWidth = WindowWidth + DataWidth;}public ControlDataRollToLeftOffsetGenerater(int WindowWidth, int DataWidth, int Speed, int InitOffset): base(WindowWidth, DataWidth, Speed){//RollWidth = WindowWidth + DataWidth;}#region 数据//private int _RollWidth;#endregion#region 属性public override int WindowWidth{get{return base.WindowWidth;}set{base.WindowWidth = value;//RollWidth = DataWidth + WindowWidth;}}public override int DataWidth{get{return base.DataWidth;}set{base.DataWidth = value;//RollWidth = DataWidth + WindowWidth;}}//public int RollWidth//{//    get//    {//        return _RollWidth;//    }//    set//    {//        if (value < 0) _RollWidth = 0;//    }//}#endregion/// <summary>/// 获取一个新的偏移量/// </summary>/// <returns></returns>public override int GetNextOffset(){if (Offset < -DataWidth){Offset = WindowWidth;}else{Offset -= Speed;}return Offset;}}
}

转载于:https://www.cnblogs.com/yedaoq/archive/2010/04/14/1711945.html

ToolStripStatusRollingLabel——滚动显示状态栏标签相关推荐

  1. Flutter web 滚动循环 title(Flutter Web端 滚动显示浏览器标签页名)

    应用场景:一般用于页面收到新消息通知时,或者正在播放音视频时浏览器标签页会循环显示标签名称,以达到提醒或表示正在进行的效果. Flutter 代码 /*** 修改html的title {repeat ...

  2. html设置ios状态栏颜色,ios 显示html标签,超链接颜色以及下划线的处理

    有的时候,我们的app需要显示html标签的效果,这个时候,如果需求不是特别复杂的话,我们都是可以使用textView来实现的.对冉Label也可以实现,但是label很难实现超链接的点击效果,所以, ...

  3. php中滚动显示文字,HTML如何实现文字的滚动效果

    在HTML中,可以通过HTML的标签来实现文字的滚动效果,通过设置标签里的不同属性来实现不同的文字的滚动效果. 在HTML中实现文字的滚动效果其实很简单,本篇文章就给大家介绍HTML 标签实现文字的滚 ...

  4. android gridview横向显示图片,Android使用Gridview单行横向滚动显示

    本文实例为大家分享了Android使用Gridview单行横向滚动显示的具体代码,供大家参考,具体内容如下 要想实现滚动显示,layout布局里必须要使用HorizontalScrollView,才能 ...

  5. HTML怎么设置自动滚动的图片,转:HTML中让图片滚动的marquee标签的使用方法

    实例: 需要滚动的文字 需要滚动的文字 也可以程序代码 也可以是图片 说明: 1.中间的内容可以为 文字,图片,也可以是由程序生成的文字或图片 2.onMouseOut="this.star ...

  6. C# :Winform窗体中文字滚动显示

    想要做到文字滚动显示,首先需要把文字写入Lable控件中,将Label控件的位置改变就可以实现文字的位置变换. 1.在窗体中添加Timer和Lable控件 2.编写代码 //滚动 Lable priv ...

  7. [Javascript]怎么样让公告不间断的滚动显示

    一.从下往上不间断滚动显示 <table width="315" border="0" align="center" cellpadd ...

  8. ​Highmaps网页图表教程之绘图区显示标签显示数据标签定位

    ​Highmaps网页图表教程之绘图区显示标签显示数据标签定位 Highmaps数据标签定位 由于数据标签是和节点一一对应,所以数据标签是依据节点位置进行定位的.本节详细讲解如何对数据标签进行定位. ...

  9. zblog php标签,201502200101 zblogphp调整“显示常用标签”个数方法

    201502200101 zblogphp调整"显示常用标签"个数方法 6年前 (2015-02-20)    作者:iMoke    分类:原创·技术    阅读次数:2509 ...

最新文章

  1. 算法----------字符串相乘(Java 版本)
  2. 日本计算机科学家谷歌评审,高一被清华姚班录取, 高三委拒谷歌offer, 一个重度网瘾少年到理论计算机科学家的蜕变...
  3. php-fpm 无法运行cli,linux-怎样让php在cli与fpm环境下运行时加载不同的扩展?
  4. 基于JindoFS+OSS构建高效数据湖
  5. 多线程编程之两阶段终止模式
  6. 谷歌眼中的云计算—李开复于浙江工商大学
  7. 洛谷P4012 深海机器人问题(费用流)
  8. Unity3D数字孪生笔记——Unity脚本篇
  9. centos下编译abseil-cpp
  10. Visio绘制时间轴、日程安排图、时间进度图的方法
  11. Android Error:Some file crunching failed, see logs for details
  12. cs服务器搭建(cobaltstrike)
  13. 影楼——Lr基础操作PS动作及批处理
  14. Building the main Guest Additions module [failed]
  15. 帝国cms ajax,帝国CMS封装的ajax加载信息框架代码
  16. 打印机生产食物?3D打印技术推出人造肉口感佳
  17. 每日一道题,划水有意义,看我不卷死你们(评论送书)
  18. 哲理故事与管理之道(11)-让自己成为领袖和榜样
  19. 安全态势感知系统java_代码分析平台CodeQL学习手记(十三) - 嘶吼 RoarTalk – 回归最本质的信息安全,互联网安全新媒体,4hou.com...
  20. 世界上十个著名悖论详解

热门文章

  1. CO1 Introduction
  2. the difference between a material and an effect
  3. pytorch保存模型参数
  4. leetcode最大矩形_柱状图中的最大矩形
  5. 推荐系统组队学习——WideDeep
  6. 动手学深度学习Pytorch Task08
  7. 深度学习的研究方向: 你会为AI转型么?
  8. java mac 怎么删_做java服务器开发,并发布到linux,那MacBookPro开发是绝佳工具
  9. android 修改APK
  10. ci php做记录删除,PHP CI APC 使用记录