首页 > 代码库 > C# 文字滚动特效(上下滚动)
C# 文字滚动特效(上下滚动)
本程序改编至网上下载的一个自定义控件,原控件是左右滚动效果,类似于跑马灯效果,由于项目需要,改编为上下滚动。
前期没有实现自动折行,今天刚加上自动折行。
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Data; using System.Windows.Forms; using System.Collections.Generic; namespace OI.Common.Controls { /* 【原功能为文字左右滚动控件】 * 此控件修改滚动方式为由下至上 * 修改人:王志超 * 时间:2014-02-10 * 修改内容:public void DrawScrollingText(Graphics canvas) */ /// <summary> /// Summary description for ScrollingTextControl. /// </summary> [ ToolboxBitmapAttribute(typeof(OI.Common.Controls.ScrollingText), "ScrollingText.bmp"), DefaultEvent("TextClicked") ] public class ScrollingText : System.Windows.Forms.Control { private Timer timer; // Timer for text animation. private string text = "Text"; // Scrolling text private float staticTextPos = 0; // The running x pos of the text private float yPos = 0; // The running y pos of the text private ScrollDirection scrollDirection = ScrollDirection.RightToLeft; // The direction the text will scroll private ScrollDirection currentDirection = ScrollDirection.LeftToRight; // Used for text bouncing private VerticleTextPosition verticleTextPosition = VerticleTextPosition.Center; // Where will the text be vertically placed private int scrollPixelDistance = 1; // How far the text scrolls per timer event private bool showBorder = true; // Show a border or not private bool stopScrollOnMouseOver = false; // Flag to stop the scroll if the user mouses over the text private bool scrollOn = true; // Internal flag to stop / start the scrolling of the text private Brush foregroundBrush = null; // Allow the user to set a custom Brush to the text Font private Brush backgroundBrush = null; // Allow the user to set a custom Brush to the background private Color borderColor = Color.Black; // Allow the user to set the color of the control border private RectangleF lastKnownRect; // The last known position of the text public ScrollingText() { // Setup default properties for ScrollingText control InitializeComponent(); //This turns off internal double buffering of all custom GDI+ drawing Version v = System.Environment.Version; if (v.Major < 2) { this.SetStyle(ControlStyles.DoubleBuffer, true); } else { this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); } this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.ResizeRedraw, true); //setup the timer object timer = new Timer(); timer.Interval = 100; //default timer interval timer.Enabled = true; timer.Tick += new EventHandler(Tick); } /**/ /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { //Make sure our brushes are cleaned up if (foregroundBrush != null) foregroundBrush.Dispose(); //Make sure our brushes are cleaned up if (backgroundBrush != null) backgroundBrush.Dispose(); //Make sure our timer is cleaned up if (timer != null) timer.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /**/ /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { //ScrollingText this.Name = "ScrollingText"; this.Size = new System.Drawing.Size(216, 40); this.Click += new System.EventHandler(this.ScrollingText_Click); } #endregion //Controls the animation of the text. private void Tick(object sender, EventArgs e) { //2014-05-10 王志超修改 RectangleF refreshRect = new RectangleF(0, 0, this.Size.Width, this.Size.Height); Region updateRegion = new Region(refreshRect); Invalidate(updateRegion); Update(); //原代码如下: ////update rectangle to include where to paint for new position ////lastKnownRect.X -= 10; ////lastKnownRect.Width += 20; //lastKnownRect.Inflate(10, 5); ////get the display rectangle //RectangleF refreshRect = lastKnownRect; //refreshRect.X = Math.Max(0, lastKnownRect.X); //refreshRect.Width = Math.Min(lastKnownRect.Width + lastKnownRect.X, this.Width); //refreshRect.Width = Math.Min(this.Width - lastKnownRect.X, refreshRect.Width); ////create region based on updated rectangle ////Region updateRegion = new Region(lastKnownRect); //Region updateRegion = new Region(refreshRect); ////repaint the control //Invalidate(updateRegion); //Update(); } //Paint the ScrollingTextCtrl. protected override void OnPaint(PaintEventArgs pe) { //Console.WriteLine(pe.ClipRectangle.X + ", " + pe.ClipRectangle.Y + ", " + pe.ClipRectangle.Width + ", " + pe.ClipRectangle.Height); //Paint the text to its new position DrawScrollingText(pe.Graphics); //pass on the graphics obj to the base Control class base.OnPaint(pe); } protected override void OnSizeChanged(EventArgs e) { p = new PointF(0, this.ClientSize.Height); base.OnSizeChanged(e); } PointF p; //Draw the scrolling text on the control public void DrawScrollingText(Graphics canvas) { canvas.SmoothingMode = SmoothingMode.HighQuality; canvas.PixelOffsetMode = PixelOffsetMode.HighQuality; //measure the size of the string for placement calculation SizeF stringSize = canvas.MeasureString(this.text, this.Font); //Calculate the begining x position of where to paint the text if (scrollOn) { //CalcTextPosition(stringSize); } //Clear the control with user set BackColor if (backgroundBrush != null) { canvas.FillRectangle(backgroundBrush, 0, 0, this.ClientSize.Width, this.ClientSize.Height); } else { canvas.Clear(this.BackColor); } // Draw the border if (showBorder) { using (Pen borderPen = new Pen(borderColor)) canvas.DrawRectangle(borderPen, 0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1); } //新增:绘制背景图片 if (this.BackgroundImage != null) { canvas.DrawImage(this.BackgroundImage, this.ClientRectangle); } //修改滚动方式为由下至上。 //修改人:王志超 //时间:2014-05-10 p = new PointF(0, p.Y - scrollPixelDistance);//设置偏移 List<string> textRows = GetStringRows(canvas, this.Font, this.text, this.Size.Width); string strDraw = ""; //自动折行处理 foreach (string str in textRows) { strDraw += str + "\n"; } stringSize = canvas.MeasureString(strDraw, this.Font); if (p.Y <= -1 * stringSize.Height) p = new PointF(0, this.ClientSize.Height);//重新开始 if (foregroundBrush == null) { using (Brush tempForeBrush = new System.Drawing.SolidBrush(this.ForeColor)) { canvas.DrawString(strDraw, this.Font, tempForeBrush, p); } } else { canvas.DrawString(strDraw, this.Font, foregroundBrush, p); } /*以下内容为原绘制方式*/ //// Draw the text string in the bitmap in memory //if (foregroundBrush == null) //{ // using (Brush tempForeBrush = new System.Drawing.SolidBrush(this.ForeColor)) // canvas.DrawString(this.text, new Font("宋体", 20), tempForeBrush, 0, staticTextPos); //} //else //{ // canvas.DrawString(this.text, new Font("宋体", 20), foregroundBrush, 0, staticTextPos); //} //lastKnownRect = new RectangleF(staticTextPos, yPos, stringSize.Width, stringSize.Height); //EnableTextLink(lastKnownRect); } /// <summary> /// 绘制文本自动换行(超出截断) /// </summary> /// <param name="graphic">绘图图面</param> /// <param name="font">字体</param> /// <param name="text">文本</param> /// <param name="recangle">绘制范围</param> private void DrawStringWrap(Graphics graphic, Font font, string text, Rectangle recangle) { List<string> textRows = GetStringRows(graphic, font, text, recangle.Width); int rowHeight = (int)(Math.Ceiling(graphic.MeasureString("测试", font).Height)); int maxRowCount = recangle.Height / rowHeight; int drawRowCount = (maxRowCount < textRows.Count) ? maxRowCount : textRows.Count; int top = (recangle.Height - rowHeight * drawRowCount) / 2; StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Near; sf.LineAlignment = StringAlignment.Center; for (int i = 0; i < drawRowCount; i++) { Rectangle fontRectanle = new Rectangle(recangle.Left, top + rowHeight * i, recangle.Width, rowHeight); graphic.DrawString(textRows[i], font, new SolidBrush(Color.Black), fontRectanle, sf); } } /// <summary> /// 将文本分行 /// </summary> /// <param name="graphic">绘图图面</param> /// <param name="font">字体</param> /// <param name="text">文本</param> /// <param name="width">行宽</param> /// <returns></returns> private List<string> GetStringRows(Graphics graphic, Font font, string text, int width) { int RowBeginIndex = 0; int rowEndIndex = 0; int textLength = text.Length; List<string> textRows = new List<string>(); for (int index = 0; index < textLength; index++) { rowEndIndex = index; if (index == textLength - 1) { textRows.Add(text.Substring(RowBeginIndex)); } else if (rowEndIndex + 1 < text.Length && text.Substring(rowEndIndex, 2) == "\r\n") { textRows.Add(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex)); rowEndIndex = index += 2; RowBeginIndex = rowEndIndex; } else if (graphic.MeasureString(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex + 1), font).Width > width) { textRows.Add(text.Substring(RowBeginIndex, rowEndIndex - RowBeginIndex)); RowBeginIndex = rowEndIndex; } } return textRows; } private void CalcTextPosition(SizeF stringSize) { switch (scrollDirection) { case ScrollDirection.RightToLeft: if (staticTextPos < (-1 * (stringSize.Width))) staticTextPos = this.ClientSize.Width - 1; else staticTextPos -= scrollPixelDistance; break; case ScrollDirection.LeftToRight: if (staticTextPos > this.ClientSize.Width) staticTextPos = -1 * stringSize.Width; else staticTextPos += scrollPixelDistance; break; case ScrollDirection.Bouncing: if (currentDirection == ScrollDirection.RightToLeft) { if (staticTextPos < 0) currentDirection = ScrollDirection.LeftToRight; else staticTextPos -= scrollPixelDistance; } else if (currentDirection == ScrollDirection.LeftToRight) { if (staticTextPos > this.ClientSize.Width - stringSize.Width) currentDirection = ScrollDirection.RightToLeft; else staticTextPos += scrollPixelDistance; } break; } //Calculate the vertical position for the scrolling text switch (verticleTextPosition) { case VerticleTextPosition.Top: yPos = 2; break; case VerticleTextPosition.Center: yPos = (this.ClientSize.Height / 2) - (stringSize.Height / 2); break; case VerticleTextPosition.Botom: yPos = this.ClientSize.Height - stringSize.Height; break; } } #region Mouse over, text link logic private void EnableTextLink(RectangleF textRect) { Point curPt = this.PointToClient(Cursor.Position); //if (curPt.X > textRect.Left && curPt.X < textRect.Right // && curPt.Y > textRect.Top && curPt.Y < textRect.Bottom) if (textRect.Contains(curPt)) { //Stop the text of the user mouse‘s over the text if (stopScrollOnMouseOver) scrollOn = false; this.Cursor = Cursors.Hand; } else { //Make sure the text is scrolling if user‘s mouse is not over the text scrollOn = true; this.Cursor = Cursors.Default; } } private void ScrollingText_Click(object sender, System.EventArgs e) { //Trigger the text clicked event if the user clicks while the mouse //is over the text. This allows the text to act like a hyperlink if (this.Cursor == Cursors.Hand) OnTextClicked(this, new EventArgs()); } public delegate void TextClickEventHandler(object sender, EventArgs args); public event TextClickEventHandler TextClicked; private void OnTextClicked(object sender, EventArgs args) { //Call the delegate if (TextClicked != null) TextClicked(sender, args); } #endregion #region Properties [ Browsable(true), CategoryAttribute("Scrolling Text"), Description("The timer interval that determines how often the control is repainted") ] public int TextScrollSpeed { set { timer.Interval = value; } get { return timer.Interval; } } [ Browsable(true), CategoryAttribute("Scrolling Text"), Description("How many pixels will the text be moved per Paint") ] public int TextScrollDistance { set { scrollPixelDistance = value; } get { return scrollPixelDistance; } } [ Browsable(true), CategoryAttribute("Scrolling Text"), Description("The text that will scroll accros the control") ] public string ScrollText { set { text = value; this.Invalidate(); this.Update(); } get { return text; } } //[ //Browsable(true), //CategoryAttribute("Scrolling Text"), //Description("What direction the text will scroll: Left to Right, Right to Left, or Bouncing") //] //public ScrollDirection ScrollDirection //{ // set // { // scrollDirection = value; // } // get // { // return scrollDirection; // } //} //[ //Browsable(true), //CategoryAttribute("Scrolling Text"), //Description("The verticle alignment of the text") //] //public VerticleTextPosition VerticleTextPosition //{ // set // { // verticleTextPosition = value; // } // get // { // return verticleTextPosition; // } //} [ Browsable(true), CategoryAttribute("Scrolling Text"), Description("Turns the border on or off") ] public bool ShowBorder { set { showBorder = value; } get { return showBorder; } } [ Browsable(true), CategoryAttribute("Scrolling Text"), Description("The color of the border") ] public Color BorderColor { set { borderColor = value; } get { return borderColor; } } //[ //Browsable(true), //CategoryAttribute("Scrolling Text"), //Description("Determines if the text will stop scrolling if the user‘s mouse moves over the text") //] //public bool StopScrollOnMouseOver //{ // set // { // stopScrollOnMouseOver = value; // } // get // { // return stopScrollOnMouseOver; // } //} [ Browsable(true), CategoryAttribute("Behavior"), Description("Indicates whether the control is enabled") ] new public bool Enabled { set { timer.Enabled = value; base.Enabled = value; } get { return base.Enabled; } } [ Browsable(false) ] public Brush ForegroundBrush { set { foregroundBrush = value; } get { return foregroundBrush; } } [ ReadOnly(true) ] public Brush BackgroundBrush { set { backgroundBrush = value; } get { return backgroundBrush; } } #endregion } public enum ScrollDirection { RightToLeft, LeftToRight, TopToBottom, BottomToTop, Bouncing } public enum VerticleTextPosition { Top, Center, Botom } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。