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无法避免。经过一个下午的研究,终于想出了一个解决办法,虽然该办法并非十分完美emwink.gif

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);
            }
        }

问题解决emsmile.gif

转载于:https://www.cnblogs.com/flick/archive/2007/06/02/768818.html

### 回答1: 以下是使用C#代码设置工具栏ToolStrip的示例: 1. 创建一个WinForm窗体,将一个ToolStrip控件拖放到窗体上。 2. 在窗体的Load事件中添加以下代码: ``` private void Form1_Load(object sender, EventArgs e) { // 添加工具栏按钮 ToolStripButton btnNew = new ToolStripButton("新建"); btnNew.Image = Properties.Resources.New; btnNew.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText; btnNew.Click += new EventHandler(btnNew_Click); toolStrip1.Items.Add(btnNew); ToolStripButton btnOpen = new ToolStripButton("打开"); btnOpen.Image = Properties.Resources.Open; btnOpen.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText; btnOpen.Click += new EventHandler(btnOpen_Click); toolStrip1.Items.Add(btnOpen); ToolStripButton btnSave = new ToolStripButton("保存"); btnSave.Image = Properties.Resources.Save; btnSave.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText; btnSave.Click += new EventHandler(btnSave_Click); toolStrip1.Items.Add(btnSave); // 添加分隔符 toolStrip1.Items.Add(new ToolStripSeparator()); // 添加下拉框 ToolStripComboBox cmbFontSize = new ToolStripComboBox(); cmbFontSize.Items.AddRange(new object[] { "12", "14", "16", "18", "20" }); cmbFontSize.SelectedIndex = ; cmbFontSize.SelectedIndexChanged += new EventHandler(cmbFontSize_SelectedIndexChanged); toolStrip1.Items.Add(cmbFontSize); } // 工具栏按钮的事件处理方法 private void btnNew_Click(object sender, EventArgs e) { // 新建文件 } private void btnOpen_Click(object sender, EventArgs e) { // 打开文件 } private void btnSave_Click(object sender, EventArgs e) { // 保存文件 } // 下拉框的事件处理方法 private void cmbFontSize_SelectedIndexChanged(object sender, EventArgs e) { // 更改字体大小 } ``` 3. 运行程序,可以看到工具栏上已经添加了三个按钮和一个下拉框。单击按钮或选择下拉框中的选项,可以触发相应的事件处理方法。 ### 回答2: 题目不明确,请您提供更多信息或者指定要回答的题目并且再次提问。谢谢! ### 回答3: C是计算机科学中一种非常重要的编程语言,它由于其简洁明了的语法、高效性以及可移植性,已经成为计算机科学领域中最受欢迎的语言之一。 首先,C语言的语法简洁明了,这让C成为了学习编程的理想语言。C语言有一些基本的语法结构,比如数据类型、变量定义和控制结构等,这些都很容易理解,因此可以快速入门。同时,许多编程语言都从C语言借鉴了语法和风格,因此学会C语言也可以更加方便地学习其他编程语言。 其次,C语言是一种高效的语言。它不像其他编程语言那样需要大量的运行时支持,而是直接映射到了机器语言中,这使得C语言的执行速度非常快。这让C语言在编写操作系统、嵌入式系统和网络应用等需要高性能的应用中表现出色。 最后,C语言是可移植的。由于C语言不依赖于特定的操作系统或硬件平台,因此可以轻松移植到各种系统上。这使得C语言在跨平台应用程序编写领域拥有广泛的应用。 总而言之,C语言是一种非常有用的编程语言,它具有简洁明了的语法、高效性以及可移植性,已经成为计算机科学领域中最受欢迎的语言之一,学会C语言能够帮助我们更好地理解计算机科学原理、编写高效的应用程序以及提高编程技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值