C# Code, Tutorials and Full Visual Studio Projects

RumorMill 4 – WPF News Ticker

Posted by on Jan 16, 2012 in Code Snippets, Featured, Projects, WPF | 5 comments

RumorMill 4 – WPF News Ticker

I used to run a few previous web sites. CodeFreezer.com was one of them. While there I wrote RumorMill4. Similar to the v5 I posted here on Jarloo, except the UI layer is considerable different. This version displays the news articles in a ticker similar to a stock ticker.

Download the Source Code

The heart of the display is the Ticker class. This class accepts a class with the news feed information and displays it.

You can view a video of the app here:

The application is quite simple, the most interesting part is the reusable ticker class which can be used to move anything you like across in ticker style, like stock quotes etc…

Here is the XAML code for the Ticker Class:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace Jarloo.RumorMill4
{
    public class Ticker where T : FrameworkElement
    {
        private readonly DispatcherTimer displayTimer = new DispatcherTimer();

        public EventHandler> ItemDisplayed;

        public bool Running { get; set; }
        public double SeperatorSize { get; set; }
        public TimeSpan Speed { get; set; }
        public Queue Items { get; set; }
        public Panel Container { get; private set; }

        public void Stop()
        {
            displayTimer.Stop();
            Running = false;
        }

        public void Start()
        {
            displayTimer.Start();
            displayTimer.Interval = new TimeSpan(0,0,0,1);
            Running = true;
        }

        public Ticker(Panel container)
        {
            SeperatorSize = 25;

            Container = container;

            Container.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            Container.Arrange(new Rect(Container.DesiredSize));

            Speed = new TimeSpan(0, 0, 0, 40);

            Items = new Queue();

            displayTimer.Tick += displayTimer_Tick;
            displayTimer.Start();
            Running = true;
        }

        private void displayTimer_Tick(object sender, EventArgs e)
        {
            DisplayNextItem();
        }

        private void DisplayNextItem()
        {
            if (Items.Count == 0) return;

            T item = Items.Dequeue();

            Container.Children.Add(item);

            AnimateMove(item);

            if (ItemDisplayed != null) ItemDisplayed(this, new ItemEventArgs(item));
        }

        private void AnimateMove(FrameworkElement e)
        {
            const double to = -500;

            e.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            e.Arrange(new Rect(e.DesiredSize));

            double from = Container.ActualWidth;

            int unitsPerSec = Convert.ToInt32(Math.Abs(from - to)/Speed.TotalSeconds);
            int nextFire = Convert.ToInt32((e.ActualWidth + SeperatorSize)/unitsPerSec);

            displayTimer.Stop();
            displayTimer.Interval = new TimeSpan(0, 0, nextFire);
            displayTimer.Start();

            TaggedDoubleAnimation ani = new TaggedDoubleAnimation
                                            {
                                                From = from,
                                                To = to,
                                                Duration = new Duration(Speed),
                                                TargetElement = e
                                            };

            ani.Completed += ani_Completed;

            TranslateTransform trans = new TranslateTransform();
            e.RenderTransform = trans;

            trans.BeginAnimation(TranslateTransform.XProperty, ani, HandoffBehavior.Compose);
        }

        private void ani_Completed(object sender, EventArgs e)
        {
            Clock clock = (Clock) sender;
            TaggedDoubleAnimation ani = (TaggedDoubleAnimation) clock.Timeline;

            FrameworkElement element = ani.TargetElement;
            Container.Children.Remove(element);
        }
    }
}

The rest of the code isn’t very difficult and doesn’t warrent a full walk-through. If your having problems with it please post a comment and I can add additional information here if needed.

More stuff you might like:

  1. RumorMill 5 – RSS, RDF and ATOM Reader
  2. Consume a News Feed
  3. WordMerge – Word Fusion Application
  4. TweetSearch – The C# Twitter Search Engine
  5. Jot the WPF Sticky Note App

5 Comments

Join the conversation and post a comment.

  1. ct

    yay! Thanks for the code :)

  2. AK

    Thanks! I was looking for this for a long time~

  3. hhlim

    Hi, which param to adjust the speed?

    I changed the displayTimer interval and Speed.. seems nothing happened.

  4. admin

    The speed property in the Ticker’s constructor sets a default, but in the example code I am overriding it in the MainWindow’s constructor when creating it:

    ticker = new Ticker(LayoutRoot) {Speed = new TimeSpan(0, 2, 0)};

    Just change it to 10 seconds or something and the tickers will travel much faster.

  5. beowshawitz

    How could you pause it on a mouse enter and then start it again on a mouse leave?

Leave a Comment

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>