C# Animated Tray Icon

Overview

Animated tray icons are a useful way of alerting users of changes to your applications state. Unfortunately the .NET frameworks tray icon offering doesn’t support animation so I decided to write a reusable component that extends the tray icon to incorporate the desired functionality. Another notable feature of this implementation is that it supports the 24×24 Windows 7 tray icons as opposed to others that rely on the scaling the 16×16 size icons up.

Download the control & sample project

Extending the non-extendable

The .NET TrayIcon class is sealed and therefore non-extendable so I have wrapped it (and some of it’s core properties and methods) within a new component to achieve extension.

Visual Studio Design Time Support

I have also made the component designer compliant by adding the relevant XML documentation markup and property definitions.

The Control Code

[AnimatedNofifyIcon.cs]

/* 
 * C# Animated Notify Icon Component
 *
 * @package uk.co.codeblog.csharp.controls.AnimatedNotifyIcon
 * @author Oliver Green 
 * @copyright  Copyright (c) 2009-2012 CodeBlog (http://www.codeblog.co.uk)
 * @license Creative Commons Attribution-ShareAlike 3.0 Unported License. (http://creativecommons.org/licenses/by-sa/3.0/)
 * Version: 0.1 $Revision: 350 $
 * Date: $Date: 2012-01-04 23:27:28 +0000 (Wed, 04 Jan 2012) $
 * 
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;

using System.Drawing;

namespace uk.co.codeblog.csharp.controls
{
    public partial class AnimatedNotifyIcon : Component
    {
        /* Timer to control the animation */
        Timer _t = new Timer();

        /* Our 'filstrip' of icons to build the animation from */
        Icon[] _icons;

        /* Which index of the film strip are we currently on? */
        int _cIndex = 0;

        /* How many times have we looped the animation so far? */
        int _loopCount = 1;
        
        /* How many times should we loop the animation for? 0 = infinite */
        int _loopNo = 0;

        /* 
         * Properties
         * Most of which wrap the NotifyIcons properties on a basic level
         * (If you want events you'll have to reference the inner NotifyIcon 
         * object
         */


        ///The text that will be displaid when the mouse hovers over the icon

        [CategoryAttribute("Appearance"),
         DescriptionAttribute("The text that will be displaid when the mouse hovers over the icon")]

        public string Text
        {
            get { return _notifyIcon.Text; }
            set { _notifyIcon.Text = value; }
        }



        ///The icon to associate with the balloon ToolTip
        
        [CategoryAttribute("Appearance"),
         DescriptionAttribute("The icon to associate with the BalloonTip")]

        public ToolTipIcon BalloonTipIcon
        {
            get { return _notifyIcon.BalloonTipIcon; }
            set { _notifyIcon.BalloonTipIcon = value; }
        }



        ///The text to associate with the balloon ToolTip
        
        [CategoryAttribute("Appearance"),
         DescriptionAttribute("The text to associate with the balloon ToolTip")]

        public string BalloonTipText
        {
            get { return _notifyIcon.BalloonTipText; }
            set { _notifyIcon.BalloonTipText = value; }
        }


        ///The title to associate with the balloon ToolTip
        
        [CategoryAttribute("Appearance"),
         DescriptionAttribute("The title to associate with the balloon ToolTip")]
        
        public string BalloonTipTitle
        {
            get { return _notifyIcon.BalloonTipTitle; }
            set { _notifyIcon.BalloonTipTitle = value; }
        }


        ///The shortcut menu to show when the user right-clicks on the icon
        
        [CategoryAttribute("Behavior"),
         DescriptionAttribute("The shortcut menu to show when the user right-clicks on the icon")]
        
        public ContextMenuStrip ContextMenuStrip
        {
            get { return _notifyIcon.ContextMenuStrip; }
            set { _notifyIcon.ContextMenuStrip = value; }
        }


        ///Determines whether the control is visible or hidden
        
        [CategoryAttribute("Behavior"),
         DescriptionAttribute("Determines whether the control is visible or hidden")]
        
        public Boolean Visible
        {
            get { return _notifyIcon.Visible; }
            set { _notifyIcon.Visible = value; }
        }


        ///Gets the underlying NotifyIcon control
        
        [CategoryAttribute("Misc"),
         DescriptionAttribute("Gets the underlying NotifyIcon control")]
    
        public NotifyIcon NotifyIcon
        {
            get { return _notifyIcon; }
        }


        ///Sets the number of times for the animation to loop (0 = Infinite)
        
        [CategoryAttribute("Behavior"),
         DescriptionAttribute("Sets the number of times for the animation to loop (0 = Infinite)")]
        
        public int Loop
        {
            get { return _loopNo; }
            set { _loopNo = value; }
        }


        ///Sets the animation frame rate (FPS)
        
        [ CategoryAttribute("Behavior"),
          DescriptionAttribute("Sets the animation frame rate (FPS)")]
        
        public int FrameRate
        {
            get { return (1000 / _t.Interval); }
            set 
            { 
                int interval = (int) Math.Ceiling(Convert.ToDouble(1000 / value));

                if (interval > 0)
                {
                    _t.Interval = interval;
                }
                else
                {
                    _t.Interval = 4;
                }
            }
        }


        ///Returns whether the animation is running or not
        
        [CategoryAttribute("Misc"),
         DescriptionAttribute("Returns whether the animation is running or not")]

        public Boolean IsRunning
        {
            get { return _t.Enabled; }
        }

        public AnimatedNotifyIcon()
        {
            InitializeComponent();
            InitializeIcon();
        }

        public AnimatedNotifyIcon(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
            InitializeIcon();
        }


        ///Sets up the tray icon

        protected void InitializeIcon()
        {
            _t.Interval = 250;
            _t.Tick += ChangeIcon;
        }


        ///Changes the icon on timer

        protected void ChangeIcon(object sender, EventArgs e)
        {
            if (_loopNo == 0 || _loopCount <= _loopNo)
            {                
                _cIndex++;
                if (_cIndex >= _icons.Length)
                {
                    _cIndex = 0;
                    _loopCount++;
                }
                _notifyIcon.Icon = _icons[_cIndex];
            }
            else
            {
                _loopCount = 1;
                this.Stop();
            }
        }


        ///Starts the animation

        public void Start()
        {
            _t.Start();
        }


        ///Stops the animation

        public void Stop()
        {
            _t.Stop();
        }


        ///Displays a balloon ToolTip in the taskbar for a specified period
        ///Time period, in millisecods, the balloon should display for

        public void ShowBalloonTip(int Timeout)
        {
            _notifyIcon.ShowBalloonTip(Timeout);
        }


        ///Displays a balloon ToolTip in the taskbar for a specified period
        ///Time period, in millisecods, the balloon should display for
        ///The title to display on the balloon tip
        ///The text to display on the balloon tip
        ///One of the System.Windows.Forms.ToolTipIcon values

        public void ShowBalloonTip(int Timeout, string TipTitle, string TipText, ToolTipIcon TipIcon)
        {
            _notifyIcon.ShowBalloonTip(Timeout, TipTitle, TipText, TipIcon);
        }


        ///Sets the animation frames
        ///Array of icons to form animation
        ///Sets the NotifyIcons current icon to the first icon in the Array

        public void SetAnimationFrames(Icon[] Icons, Boolean MoveToFirstFrame = true)
        {
            if (Icons.Length > 0)
            {
                _icons = Icons;

                if (MoveToFirstFrame)
                {
                    _notifyIcon.Icon = Icons[0];
                    _cIndex = 0;
                }


            }
        }

        

    }
}

[AnimatedNofifyIcon.Designer.cs]

/* 
 * Demo Form
 *
 * @package uk.co.codeblog.csharp.controls.AnimatedNotifyIcon
 * @author Oliver Green 
 * @copyright  Copyright (c) 2009-2012 CodeBlog (http://www.codeblog.co.uk)
 * @license Creative Commons Attribution-ShareAlike 3.0 Unported License. (http://creativecommons.org/licenses/by-sa/3.0/)
 * Version: 0.1 $Revision: 350 $
 * Date: $Date: 2012-01-04 23:27:28 +0000 (Wed, 04 Jan 2012) $
 * 
 */

using System.Drawing;

namespace uk.co.codeblog.csharp.controls
{
    [ToolboxBitmapAttribute(typeof(AnimatedNotifyIcon),
    "AnimatedNotifyIcon.ico")]
    partial class AnimatedNotifyIcon
    {
        /// 
        /// Required designer variable.
        /// 
        private System.ComponentModel.IContainer components = null;

        ///  
        /// Clean up any resources being used.
        /// 
        /// true if managed resources should be disposed; otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// 
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// 
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this._notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
            // 
            // trayIcon
            // 
            this._notifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            this._notifyIcon.Text = "trayIcon";
            this._notifyIcon.Visible = true;

        }

        #endregion

        private System.Windows.Forms.NotifyIcon _notifyIcon;


    }
}
Tags:
Post comment as twitter logo facebook logo
Sort: Newest | Oldest