原文:WPF 实现跑马灯效果的Label控件,数据绑定方式实现
项目中需要使用数据绑定的方式实现跑马灯效果的Label,故重构了Label控件;具体代码如下
using System;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using Tool;
namespace iMasteRayClient.View.ViewUnit
{
public class UIScrollingLabel : Label
{
/// <summary>
/// 滚动一循环字幕停留的秒数,单位为毫秒,默认值停留3秒
/// </summary>
public int StopSecond
{
get { return _StopSecond; }
set
{
_StopSecond = value;
}
}
/// <summary>
/// 滚动的速度
/// </summary>
public double RunSpeed
{
get { return _RunSpeed; }
set
{
_RunSpeed = value;
MarqueeTimer.Interval = _RunSpeed;
}
}
/// <summary>
/// 滚动文字源
/// </summary>
public string TextSource
{
get { return _TextSource; }
set
{
_TextSource = value;
_TempString = _TextSource + " ";
_OutText = _TempString;
}
}
private string SetContent
{
get { return Content.ToString(); }
set
{
Content = value;
}
}
/// <summary>
/// 构造函数
/// </summary>
public UIScrollingLabel(double m_Width, double m_Height,string m_Text)
{
this.Width = m_Width;
this.Height = m_Height;
MarqueeTimer.Interval = _RunSpeed;//文字移动的速度
MarqueeTimer.Enabled = false ; //开启定时触发事件
MarqueeTimer.Elapsed += new ElapsedEventHandler(MarqueeTimer_Elapsed);//绑定定时事件
this.Loaded += new RoutedEventHandler(ScrollingTextControl_Loaded);//绑定控件Loaded事件
this.TargetUpdated += UIScrollingLabel_TargetUpdated;//绑定使用数据绑定方式修改Content后的响应事件,即判断是否开启滚动定时器
}
private void UIScrollingLabel_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
{
TextSource = this.Content.ToString() ;
if (GetTextDisplayWidthHelper.GetTextDisplayWidth(this) > this.Width)
{
MarqueeTimer.Enabled = true;
}
else
{
MarqueeTimer.Enabled = false;
}
}
void ScrollingTextControl_Loaded(object sender, RoutedEventArgs e)
{
_TextSource = SetContent;
_TempString = _TextSource + " ";
_OutText = _TempString;
_SignTime = DateTime.Now;
}
void MarqueeTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (string.IsNullOrEmpty(_OutText)) return;
if (_OutText.Substring(1) + _OutText[0] == _TempString)
{
if (_IfFirst)
{
_SignTime = DateTime.Now;
}
if ((DateTime.Now - _SignTime).TotalMilliseconds > _StopSecond)
{
_IfFirst = true;
}
else
{
_IfFirst = false;
return;
}
}
_OutText = _OutText.Substring(1) + _OutText[0];
Dispatcher.BeginInvoke(new Action(() =>
{
SetContent = _OutText;
}));
}
/// <summary>
/// 定时器
/// </summary>
Timer MarqueeTimer = new Timer();
/// <summary>
/// 滚动文字源
/// </summary>
String _TextSource = "";
/// <summary>
/// 输出文本
/// </summary>
String _OutText = string.Empty;
/// <summary>
/// 过度文本存储
/// </summary>
string _TempString = string.Empty;
/// <summary>
/// 文字的滚动速度
/// </summary>
double _RunSpeed = 200;
DateTime _SignTime;
bool _IfFirst = true;
/// <summary>
/// 滚动一循环字幕停留的秒数,单位为毫秒,默认值停留3秒
/// </summary>
int _StopSecond = 3000;
}
}
其中需要判断文本的显示长度,故实现了一个测量文本长度的工具类:
using System;
using System.Windows;
using System.Windows.Media;
using System.Globalization;
using System.Windows.Controls;
namespace Tool
{
static class GetTextDisplayWidthHelper
{
public static Double GetTextDisplayWidth(Label label)
{
return GetTextDisplayWidth(label.Content.ToString(), label.FontFamily, label.FontStyle, label.FontWeight, label.FontStretch, label.FontSize);
}
public static Double GetTextDisplayWidth(string str, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch,double FontSize)
{
var formattedText = new FormattedText(
str,
CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
FontSize,
Brushes.Black
);
Size size = new Size(formattedText.Width, formattedText.Height);
return size.Width;
}
}
}
参考﹎蓝言觅ぷ雨的文章,连接:http://www.cnblogs.com/lanymy/archive/2012/07/11/2586643.html 表示感谢