Click here to Skip to main content
15,887,214 members
Articles / Programming Languages / C#

A different take on the .NET ToolTip/BalloonTip

Rate me:
Please Sign up or sign in to vote.
1.22/5 (9 votes)
15 Feb 2008CPOL 37.2K   172   13   10
How to implement a .NET ToolTip/BalloonTip using the standard .NET Form.

Introduction

Standard NotificationIcon ToolTip is only 64 chars wide, and BalloonTip is too intrusive and inflexible to use. I have written my own version of a tooltip that gives me more text and is easy to use and unobtrusive.

Background

This code uses standard WinForms controls and techniques. I looked around and found esoteric implementations using PInvoke and the like. So I created this simpler (at least for me) way of giving me what I want.

Here is a bitmap of what it looks like while hovering over an icon:

InfoTip.JPG

Using the Code

The code is just a method (InfoTip) and some event handlers. You will note that it is simple to use and hopefully it will give you some ideas to take it further. It can certainly be expanded to have other controls and functionality. I should also mention that this is my first article, so please forgive me if I missed anything in the way of article entry etiquette.

C#
//the InfoTip method takes in a whole seconds int value
private void InfoTip(int theTimeOut)
{
    //we want the current position so we can calculate where the 
    //info tip will be displayed relative to the NotificationIcon
    Point aXY = Cursor.Position;

     //create a new form for housing the text label 
     _InfoTipForm = new Form();

     //register load and formclosing event so that
     //we can control interaction with  context menu
     _InfoTipForm.FormClosing += 
       new FormClosingEventHandler(_InfoTipForm_FormClosing);          
     _InfoTipForm.Load += new EventHandler(_InfoTipForm_Load);

     //set up the form's attributes to mimic standard ToolTip look and feel
     _InfoTipForm.FormBorderStyle = FormBorderStyle.None;
     _InfoTipForm.BackColor = Color.Cornsilk;
     _InfoTipForm.ControlBox = false;
     _InfoTipForm.MaximizeBox = false;
     _InfoTipForm.MinimizeBox = false;
     _InfoTipForm.Width = 0; //these two prop settings prevent flashing
     _InfoTipForm.Height = 0; //when the form draws itself
     _InfoTipForm.TopMost = true;
     _InfoTipForm.ShowInTaskbar = false;
     _InfoTipForm.Visible = true; 


     //this is the label that will display the Tip's text
     //this is what allows us to go beyond
     //the 64 char limit of the standard tooltip
     //but you can also make this be any container type
     //of control to hold an image, rich text, etc...
     Label aInfoTip = new Label();

     //format to mimic ToolTip look and feel
     aInfoTip.BackColor = Color.Cornsilk;
     aInfoTip.ForeColor = Color.Black;
     aInfoTip.Font = new Font("Arial", 9, FontStyle.Regular);
     aInfoTip.AutoSize = true; 
     aInfoTip.Location = new Point(0, 0);
     aInfoTip.TextAlign = ContentAlignment.MiddleLeft;
     aInfoTip.Visible = true;
     //for my application I assign the text
     //on a global but you can pass it in.
     aInfoTip.Text = _NotifyText;
     aInfoTip.Refresh();//forces control to redraw
          
     //now we add the label to the form and
     //set the form size to the label size
     _InfoTipForm.Controls.Add(aInfoTip);
     _InfoTipForm.Width = aInfoTip.Width;
     _InfoTipForm.Height = aInfoTip.Height; 

     //keep the form within the screen viewing area and above the icon
     if(Screen.PrimaryScreen.Bounds.Width - aXY.X < _InfoTipForm.Width)
        _InfoTipForm.DesktopLocation = 
            new Point(aXY.X - _InfoTipForm.Width, aXY.Y - 34);
     else
        _InfoTipForm.DesktopLocation = new Point(aXY.X, aXY.Y - 34);

     //force form to refresh
     _InfoTipForm.Refresh();
     _InfoTipForm.Show(); 

     //global manualresetevent that waits the timeout period,
     //used to close the tip before timeout ends
     _TipWait.WaitOne(theTimeOut * 1000, false);

     //close the form when done waiting
     _InfoTipForm.Close();
    
     //reset the signaller so it's ready the next time our tip shows
     _TipWait.Reset(); 

}
///////////////////////////////////////////////////////////////////////////

//the info tip form global
Form _InfoTipForm;      
//control the showing of the tip
bool _isCanShowInfoTip=true;
//wait signaller
ManualResetEvent _TipWait=new ManualResetEvent();


//when the infottip form loads set the show controller boolean to false
private void _InfoTipForm_Load(object sender, EventArgs e)
{
     _isCanShowInfoTip = false;
}//_InfoTipForm_Load

//when the tip form closes then we can show the tip again
private void _InfoTipForm_FormClosing(object sender, FormClosingEventArgs e)
{
     _isCanShowInfoTip = true;
}//_InfoTipForm_FormClosing

//contextmenu and infotip are mutually exclusive,
//so when context menu shows, infotip closes
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
    _isCanShowInfoTip = false;
    //tell the signaller to stop blocking and continue
    //so the tip can close before the timeout period
    _TipWait.Set();
}//contextMenuStrip1_Opening

//show the infotip on mousemove (simulates hover)
//this is the InfoTip's entry point
private void notifyIcon1_MouseMove(object sender, MouseEventArgs e)
{
    //if we can show the tip and there's
    //no contextmenu showing then create the infotip
    if(_isCanShowInfoTip && !contextMenuStrip1.Visible)
        InfoTip(3);//timeout of three seconds
}//notifyIcon1_MouseMove

Points of Interest

This is just a simple implementation for my own needs, but you could certainly take this and expand on it, make it more robust for your needs.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
panenhan9-Sep-09 18:56
panenhan9-Sep-09 18:56 
GeneralI voted you a 2, and here's why... Pin
Justin Perez15-Feb-08 2:34
Justin Perez15-Feb-08 2:34 
GeneralRe: I voted you a 2, and here's why... Pin
PhrankBooth15-Feb-08 4:05
PhrankBooth15-Feb-08 4:05 
GeneralRe: I voted you a 2, and here's why... Pin
PhrankBooth15-Feb-08 4:31
PhrankBooth15-Feb-08 4:31 
GeneralPlease provide a screen shot Pin
Saar Yahalom15-Feb-08 0:12
Saar Yahalom15-Feb-08 0:12 
GeneralRe: Please provide a screen shot Pin
PhrankBooth15-Feb-08 2:14
PhrankBooth15-Feb-08 2:14 
GeneralRe: Please provide a screen shot Pin
PhrankBooth15-Feb-08 4:32
PhrankBooth15-Feb-08 4:32 
GeneralGood article but Pin
rippo14-Feb-08 20:26
rippo14-Feb-08 20:26 
GeneralRe: Good article but Pin
PhrankBooth15-Feb-08 2:13
PhrankBooth15-Feb-08 2:13 
GeneralRe: Good article but Pin
PhrankBooth15-Feb-08 4:32
PhrankBooth15-Feb-08 4:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.