A simple Text Marquee Control in Silverlight

marq1

A Silverlight text marquee is a scrolling piece of text displayed either horizontally across or vertically down your container. Here i will describe how I came up to make a marquee text control using Canvas and TextBlock. This marquee text control scrolls text in Left to right, right to left, top to bottom and bottom to top. The following three techniques are used to achieve marquee animation:

Negative Positioning in canvas: If we set negative value to any of the positioning property of Canvas: Left, Right, Top and Bottom for an UIelement , Canvas draws that UIelement outside of Canvas area.

Clip Geometry: In WPF, if you set the value of the ClipToBounds property of canvas to true, Canvas will clip its children when they go outside of Canvas.But there is no ClipToBounds property of canvas.Every UIelement has a Property named clip, which is Geometry type. You can set any geometry used to define the outline of the contents of an element. Only the area that is within the region of the geometry will be visible. Portion of UIelement outside the geometry will be visually clipped in the rendered layout. To clip the marquee when they go outside of Canvas (container), I have used rectangle geometry as clip geometry of the Canvas.

Changing Position of UIelement continuously: By changing continuously any of the canvas positioning property Left and Top, we can get moving text. Here marquee text control is a user control consists of TextBlock and canvas.

The XAML of marquee text control is in the following:

   1: <UserControl x:Class="SilverlightMarqueeText.MarqueeText"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   4:     <Canvas Name="canMain" >
   5:         <TextBlock Name="tbmarquee"> </TextBlock>
   6:     </Canvas>
   7: </UserControl>

How is Left to right marquee text implemented in this control?

Here a canvas is used as the container of marquee text. To move the text outside of canvas negative Left property of canvas is used. However, if negative left property of canvas is applied to any UIelement like TextBlock, it will go outside of its parent container but will still remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set a rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation left property of canvas for that element is being changed continuously to get moving text. The whole thing is done using the following code.

   1: private void LeftToRightMarquee()
   2:      {
   3:          RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:          rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:          canMain.Clip = rectangleGeometry;
   6:          double height = canMain.Height - tbmarquee.ActualHeight;
   7:          tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
   8:          DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:          doubleAnimation.From = -tbmarquee.ActualWidth;
  10:          doubleAnimation.To = canMain.Width;
  11:          doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:          doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:          Storyboard storyboard = new Storyboard();
  14:          storyboard.Children.Add(doubleAnimation);
  15:          Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:          Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
  17:          storyboard.Begin();
  18:      } 

How is right to left marquee text implemented in this control?

As we know, a canvas is used as the container of marquee text. Here marquee text is moved outside of canvas area equal to marquee text width and it is moved equal to canvas width using double animation. To move the text outside of canvas in the right direction, the value of left property of canvas is set equal to the width of the canvas. By this way, marquee text will go outside of its parent container but will remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation left property of canvas for that element is being changed continuously to get moving text. The whole thing is done using the following code.

   1: private void RightToLeftMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double height = canMain.Height - tbmarquee.ActualHeight;
   7:     tbmarquee.Margin = new Thickness(0, height / 2, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = canMain.Width;
  10:     doubleAnimation.To = -tbmarquee.ActualWidth;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Left)"));
  17:     storyboard.Begin();
  18: }

How is top to bottom marquee text implemented in this control?

Here marquee text is moved outside of canvas area equal to marquee text height and to behave like scrolling text, it is moved equal to canvas height using double animation. To move the text outside of canvas in the top direction, negative top property of canvas is used. However, if someone uses negative top property of canvas, it will go outside of its parent container but will remain visible outside of the parent container. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation top property of canvas for that element is being changed continuously to get moving text in the top to bottom direction. The whole thing is done using the following code.

   1: private void TopToBottomMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double width = canMain.Width - tbmarquee.ActualWidth;
   7:     tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = -tbmarquee.ActualHeight;
  10:     doubleAnimation.To = canMain.Height;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
  17:     storyboard.Begin();
  18: }

How is bottom to top marquee text implemented in this control?

To behave like each character coming out at a time, marquee text is placed outside of canvas area equal to marquee text height. To behave like scrolling text, it is moved equal to canvas height using double animation in the bottom to top direction. To place the text outside of canvas in the bottom direction, the value of top property of canvas is set equal to the height of the Canvas. To make marquee text invisible outside of canvas, i have set rectangle geometry with same size of Canvas as clip geometry of the Canvas. Then using double animation on top property of canvas for that element is being changed continuously to get moving text in the top to bottom direction. The whole thing is done using the following code.

   1: private void BottomToTopMarquee()
   2: {
   3:     RectangleGeometry rectangleGeometry = new RectangleGeometry();
   4:     rectangleGeometry.Rect = new Rect(new Point(0, 0), new Size(canMain.Width, canMain.Height));
   5:     canMain.Clip = rectangleGeometry;
   6:     double width = canMain.Width - tbmarquee.ActualWidth;
   7:     tbmarquee.Margin = new Thickness(width / 2, 0, 0, 0);
   8:     DoubleAnimation doubleAnimation = new DoubleAnimation();
   9:     doubleAnimation.From = canMain.Height;
  10:     doubleAnimation.To = -tbmarquee.ActualHeight;
  11:     doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
  12:     doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(_marqueeTimeInSeconds));
  13:     Storyboard storyboard = new Storyboard();
  14:     storyboard.Children.Add(doubleAnimation);
  15:     Storyboard.SetTarget(doubleAnimation, tbmarquee);
  16:     Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
  17:     storyboard.Begin();
  18: }
You can download the sample code from here. Hope this will save some of your time.

5 Comments

  • Hi, thanks for this great control!
    Only one issue I've encountered. I'm trying to load the content into marquee dynamically (some rss feeds) and I want to scroll the text horizontally on one line. But sometimes I'm getting the line breaks, and text is scrolled in two lines. The strange thing is that I cant determine the cause of this line breaking. It depends on font size, and also on content string length. How can I make the text to be displayed only in one line?

  • Is it possible to use hyperlinks in the tbmarquee TextBlock (MarqueeTextControl.xaml)?

    Or is it possible to use hyperlinks in the MarqueeContent attribute of the m:MarqueeText tag?

    I would like to have multiple hyperlinks scrolling in a marquee.

    Thank you!

  • Is it possible to use hyperlinks in the tbmarquee TextBlock (MarqueeTextControl.xaml)?

    Or is it possible to use hyperlinks in the MarqueeContent attribute of the m:MarqueeText tag (MainPage.xaml)?

    I would like to have multiple hyperlinks scrolling in a marquee.

    Thank you!

  • In place of bangladesh how to use large content through code behind. I'm assigning large content to textblock using a string variable with large content.

    Suppose,
    tbmarquee.Text = "BangladeshFor Left to right marquee: use Left Property of Canvas For right to left marquee: use Right Property of Canvas For upward marquee: use Bottom Property of Canvas For Downward marquee: use Top Property of Canvas The used XAML for this is in the following";

    How to display this complete text in the marquee

  • This control has some problem while dynamically loading the data.
    @Razan, do try to create a MVVM based example

Comments have been disabled for this content.