65.9K
CodeProject 正在变化。 阅读更多。
Home

关于 .NET ToolTip/BalloonTip 的不同实现方式

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.22/5 (9投票s)

2008年2月14日

CPOL
viewsIcon

38449

downloadIcon

189

如何使用标准的 .NET Form 实现 .NET ToolTip/BalloonTip。

引言

标准的 NotificationIcon ToolTip 宽度仅为 64 个字符,而 BalloonTip 使用起来过于突兀且不够灵活。 我编写了自己的工具提示版本,它能显示更多文本,并且易于使用且不显眼。

背景

这段代码使用了标准的 WinForms 控件和技术。 我查阅了一些资料,发现了一些使用 PInvoke 等方法实现的复杂版本。 因此,我创建了这种更简单(至少对我来说)的方式来实现我想要的功能。

以下是在鼠标悬停在图标上时显示的位图

InfoTip.JPG

Using the Code

这段代码只是一个方法(InfoTip)和一些事件处理程序。 您会注意到它使用起来很简单,希望它能给您一些进一步开发的思路。 它可以肯定地扩展为包含其他控件和功能。 我还应该提到,这是我的第一篇文章,请原谅我可能遗漏了任何文章规范。

//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

关注点

这只是一个简单的实现,满足我自己的需求,但您可以肯定地以此为基础进行扩展,并使其更加健壮以满足您的需求。

© . All rights reserved.