ToolStrip工具条显示ToolTip提示信息出现异常的解决方法
ToolStrip工具条显示ToolTip提示信息出现异常是.Net2.0的一个Bug,并且该异常无法在窗口中直接捕捉。该错误经常出现在浮动窗口上。
会出现异常的源码:ToolStripException.rar
修复后的源码:ToolStripTest.rar
环境:Visual Studio 2005(C#)
1、新建一个“Windows应用程序”项目;
2、在项目中新建一个Form窗口,这样系统中就有Form1和Form2两个窗口;
3、在Form1上添加一个ToolStrip,并在ToolStrip上添加一个ToolStripButton;
注意:保持toolStrip1.ShowItemToolTips为True,并且toolStripButton1.ToolTipText不为空;
4、在Form1上一个Button,并在Click事件中添加如下代码:
private void button1_Click(object sender, EventArgs e)
{
Form2 form = new Form2();
form.Controls.Add(this.toolStrip1);
form.ShowDialog();
this.Controls.Add(this.toolStrip1);
}
5、运行程序,点击Button1,弹出Form2,移动鼠标到toolStripButton1上显示提示,关闭Form2,将鼠标移到toolStripButton1,出现如下异常:
未处理 System.InvalidOperationException
Message="窗口句柄已存在。"
Source="System.Windows.Forms"
StackTrace:
在 System.Windows.Forms.NativeWindow.CheckReleased()
在 System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
在 System.Windows.Forms.ToolTip.CreateHandle()
在 System.Windows.Forms.ToolTip.Hide(IWin32Window win)
在 System.Windows.Forms.ToolStrip.UpdateToolTip(ToolStripItem item)
在 System.Windows.Forms.ToolStripItem.OnMouseHover(EventArgs e)
在 System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
在 System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
在 System.Windows.Forms.MouseHoverTimer.OnTick(Object sender, EventArgs e)
在 System.Windows.Forms.Timer.OnTick(EventArgs e)
在 System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.Run(Form mainForm)
在 ToolStripTest.Program.Main() 位置 E:\TestSource\ToolStripTest\ToolStripTest\Program.cs:行号 17
在 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
注意:如果先在Form1上显示提示,则不会出现上述异常。
原因分析:
ToolStrip中有个私有的ToolTip属性,当显示ToolTip时,ToolStrip将其初始化在第一个父窗口中;然而当ToolStrip的父窗口发生变化时,ToolStrip并没有通知ToolTip其父窗口已经发生变化。因此当该父窗口销毁时,错误就发生了。
解决方法:
由于ToolTip是私有的,无法直接对其进行操作,因此在这种情况下该Bug无法避免。经过一个下午的研究,终于想出了一个解决办法,虽然该办法并非十分完美
1、将toolStrip1.ShowItemToolTips设为False;
2、在Form1上添加ToolTip;
3、在Form1的构造函数添加如下代码:
public Form1()
{
InitializeComponent();
foreach (ToolStripItem item in this.toolStrip1.Items)
{
item.MouseHover += new EventHandler(item_MouseHover);
}
}
void item_MouseHover(object sender, EventArgs e)
{
toolTip1.RemoveAll();
toolTip1.Hide(toolStrip1);
Cursor current = Cursor.Current;
if (current != null)
{
Point location = Cursor.Position;
location.Y += toolStrip1.Cursor.Size.Height - current.HotSpot.Y;
location = toolStrip1.PointToClient(location);
toolTip1.Show((sender as ToolStripItem).ToolTipText, toolStrip1, location, toolTip1.AutoPopDelay);
}
}
问题解决
posted on 2007-06-02 17:39 flick.huang 阅读(1879) 评论(4) 编辑 收藏 举报