I'm trying to display a tooltip when mouse hovers over a disabled control. Since a disabled control does not handle any events, I have to do that in the parent form. I chose to do this by handling the MouseMove
event in the parent form. Here's the code that does the job:
void Form1_MouseMove(object sender, MouseEventArgs e)
{
m_toolTips.SetToolTip(this, "testing tooltip on " + DateTime.Now.ToString());
string tipText = this.m_toolTips.GetToolTip(this);
if ((tipText != null) && (tipText.Length > 0))
{
Point clientLoc = this.PointToClient(Cursor.Position);
Control child = this.GetChildAtPoint(clientLoc);
if (child != null && child.Enabled == false)
{
m_toolTips.ToolTipTitle = "MouseHover On Disabled Control";
m_toolTips.Show(tipText, this, 10000);
}
else
{
m_toolTips.ToolTipTitle = "MouseHover Triggerd";
m_toolTips.Show(tipText, this, 3000);
}
}
}
The code does handles the tooltip display for the disabled control. The problem is that when mouse hovers over a disabled control, the tooltip keeps closing and redisplay again. From the display time I added in the tooltip, when mouse is above the parent form, the MouseMove
event gets called roughly every 3 seconds, so the tooltip gets updated every 3 seconds. But when mouse is over a disabled control, the tooltip refreshes every 1 second. Also, when tooltip refreshes above form, only the text gets updated with a brief flash. But when tooltip refreshes above a disabled control, the tooltip windows closes as if mouse is moving into a enabled control and the tooltip is supposed to be closed. but then the tooltip reappears right away.
Can someone tell me why is this? Thanks.
you can show the tooltip only once when mouse hits the disbled control and then hide it when mouse leaves it. Pls, take a look at the code below, it should be showing a tooltip message for all the disabled controls on the form
private ToolTip _toolTip = new ToolTip();
private Control _currentToolTipControl = null;
public Form1()
{
InitializeComponent();
_toolTip.SetToolTip(this.button1, "My button1");
_toolTip.SetToolTip(this.button2, "My button2");
_toolTip.SetToolTip(this.textBox1, "My text box");
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Control control = GetChildAtPoint(e.Location);
if (control != null)
{
if (!control.Enabled && _currentToolTipControl == null)
{
string toolTipString = _toolTip.GetToolTip(control);
// trigger the tooltip with no delay and some basic positioning just to give you an idea
_toolTip.Show(toolTipString, control, control.Width/2, control.Height/2);
_currentToolTipControl = control;
}
}
else
{
if (_currentToolTipControl != null) _toolTip.Hide(_currentToolTipControl);
_currentToolTipControl = null;
}
}
hope this helps, regards
The answer turned out to be a bit simpler, but needed to be applied at all times.
void OrderSummaryDetails_MouseMove(object sender, MouseEventArgs e)
{
Control control = GetChildAtPoint(e.Location);
if (control != null)
{
string toolTipString = mFormTips.GetToolTip(control);
this.mFormTips.ShowAlways = true;
// trigger the tooltip with no delay and some basic positioning just to give you an idea
mFormTips.Show(toolTipString, control, control.Width / 2, control.Height / 2);
}
}
I tried many but ended up using this simple trick which I think it is more effective.
Create a subclass(CustomControl with just base control in it) which extends UserControl
then instead of setting "Enabled" property to false create a Method which disables just basecontrol in it instead of whole CustomControl.
Set the tool tip on CustomControl still will be able to fire eventhandlers setting the basecontrol disabled. This works wherever CustomControl is in use rather than coding on every form you use with.
Here is the hint.. :)
public partial class MyTextBox : UserControl
{
...
...
...
public void DisableMyTextBox()
{
this.txt.Enabled = false; //txt is the name of Winform-Textbox from my designer
this.Enabled = true;
}
public void EnableMyTextBox()
{
this.txt.Enabled = true;
this.Enabled = true;
}
//set the tooltip from properties tab in designer or wherever
}
In case of TextBox control, making it as readonly solved the issue.
Here is how I solved this problem
I have an application that generates code automatically for a PIC32MX.
The application has 3 Tab Pages text = PWM, ADC and UART.
On each Tab Page I have one Check Box text = RPA0
The intention is, when a peripheral uses RPA0, the other peripheral is prevented
from using that pin, by disabling it on the other pages, and a tooltip text must pop up
on the disabled check boxs saying (example "Used by PWM")
what peripheral is using that pin.
The problem is that the tooltip text won't pop up on a disabled check box.
To solve the problem, I just removed the text of the check boxes and inserted labels with the text the check box should have.
When a check box is checked, the other check boxes are disabled and the label next to it takes a tool tip text.
As the label is enabled, the tooltip text pops up, even on a disabled check box.
Double the work, half the complexity.
Here is the code and the designer for C# 2010
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void cb_ADC_RPA0_CheckedChanged(object sender, EventArgs e)
{
/* Disable pin on other peripherals */
cb_UART_RPA0.Enabled = !((CheckBox)sender).Checked;
cb_PWM_RPA0.Enabled = !((CheckBox)sender).Checked;
SetTootTip((CheckBox)sender, lbl_PWM_RPA0, lbl_UART_RPA0, "ADC");
}
private void cb_PWM_RPA0_CheckedChanged(object sender, EventArgs e)
{
/* Disable pin on other peripherals */
cb_UART_RPA0.Enabled = !((CheckBox)sender).Checked;
cb_ADC_RPA0.Enabled = !((CheckBox)sender).Checked;
SetTootTip((CheckBox)sender, lbl_ADC_RPA0, lbl_UART_RPA0, "PWM");
}
private void cb_UART_RPA0_CheckedChanged(object sender, EventArgs e)
{
/* Disable pin on other peripherals */
cb_ADC_RPA0.Enabled = !((CheckBox)sender).Checked;
cb_PWM_RPA0.Enabled = !((CheckBox)sender).Checked;
SetTootTip((CheckBox)sender, lbl_ADC_RPA0, lbl_PWM_RPA0, "UART");
}
void SetTootTip(CheckBox sender, Label lbl1, Label lbl2, string text)
{
/* Update tooltip on the other labels */
if (sender.Checked)
{
toolTip1.SetToolTip(lbl1, "Used by " + text);
toolTip1.SetToolTip(lbl2, "Used by " + text);
}
else
{
toolTip1.SetToolTip(lbl1, "");
toolTip1.SetToolTip(lbl2, "");
}
}
}
}
namespace WindowsFormsApplication1
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tpPWM = new System.Windows.Forms.TabPage();
this.tpUART = new System.Windows.Forms.TabPage();
this.tpADC = new System.Windows.Forms.TabPage();
this.cb_PWM_RPA0 = new System.Windows.Forms.CheckBox();
this.cb_ADC_RPA0 = new System.Windows.Forms.CheckBox();
this.lbl_PWM_RPA0 = new System.Windows.Forms.Label();
this.lbl_ADC_RPA0 = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.lbl_UART_RPA0 = new System.Windows.Forms.Label();
this.cb_UART_RPA0 = new System.Windows.Forms.CheckBox();
this.tabControl1.SuspendLayout();
this.tpPWM.SuspendLayout();
this.tpUART.SuspendLayout();
this.tpADC.SuspendLayout();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tpPWM);
this.tabControl1.Controls.Add(this.tpUART);
this.tabControl1.Controls.Add(this.tpADC);
this.tabControl1.Location = new System.Drawing.Point(12, 12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(629, 296);
this.tabControl1.TabIndex = 0;
//
// tpPWM
//
this.tpPWM.Controls.Add(this.lbl_PWM_RPA0);
this.tpPWM.Controls.Add(this.cb_PWM_RPA0);
this.tpPWM.Location = new System.Drawing.Point(4, 22);
this.tpPWM.Name = "tpPWM";
this.tpPWM.Padding = new System.Windows.Forms.Padding(3);
this.tpPWM.Size = new System.Drawing.Size(621, 270);
this.tpPWM.TabIndex = 0;
this.tpPWM.Text = "PWM";
this.tpPWM.UseVisualStyleBackColor = true;
//
// tpUART
//
this.tpUART.Controls.Add(this.cb_UART_RPA0);
this.tpUART.Controls.Add(this.lbl_UART_RPA0);
this.tpUART.Location = new System.Drawing.Point(4, 22);
this.tpUART.Name = "tpUART";
this.tpUART.Padding = new System.Windows.Forms.Padding(3);
this.tpUART.Size = new System.Drawing.Size(621, 270);
this.tpUART.TabIndex = 1;
this.tpUART.Text = "UART";
this.tpUART.UseVisualStyleBackColor = true;
//
// tpADC
//
this.tpADC.Controls.Add(this.lbl_ADC_RPA0);
this.tpADC.Controls.Add(this.cb_ADC_RPA0);
this.tpADC.Location = new System.Drawing.Point(4, 22);
this.tpADC.Name = "tpADC";
this.tpADC.Padding = new System.Windows.Forms.Padding(3);
this.tpADC.Size = new System.Drawing.Size(621, 270);
this.tpADC.TabIndex = 2;
this.tpADC.Text = "ADC";
this.tpADC.UseVisualStyleBackColor = true;
//
// cb_PWM_RPA0
//
this.cb_PWM_RPA0.AutoSize = true;
this.cb_PWM_RPA0.Location = new System.Drawing.Point(17, 65);
this.cb_PWM_RPA0.Name = "cb_PWM_RPA0";
this.cb_PWM_RPA0.Size = new System.Drawing.Size(15, 14);
this.cb_PWM_RPA0.TabIndex = 0;
this.cb_PWM_RPA0.UseVisualStyleBackColor = true;
this.cb_PWM_RPA0.CheckedChanged += new System.EventHandler(this.cb_PWM_RPA0_CheckedChanged);
//
// cb_ADC_RPA0
//
this.cb_ADC_RPA0.AutoSize = true;
this.cb_ADC_RPA0.Location = new System.Drawing.Point(17, 65);
this.cb_ADC_RPA0.Name = "cb_ADC_RPA0";
this.cb_ADC_RPA0.Size = new System.Drawing.Size(15, 14);
this.cb_ADC_RPA0.TabIndex = 1;
this.cb_ADC_RPA0.UseVisualStyleBackColor = true;
this.cb_ADC_RPA0.CheckedChanged += new System.EventHandler(this.cb_ADC_RPA0_CheckedChanged);
//
// lbl_PWM_RPA0
//
this.lbl_PWM_RPA0.AutoSize = true;
this.lbl_PWM_RPA0.Location = new System.Drawing.Point(38, 65);
this.lbl_PWM_RPA0.Name = "lbl_PWM_RPA0";
this.lbl_PWM_RPA0.Size = new System.Drawing.Size(35, 13);
this.lbl_PWM_RPA0.TabIndex = 1;
this.lbl_PWM_RPA0.Text = "RPA0";
//
// lbl_ADC_RPA0
//
this.lbl_ADC_RPA0.AutoSize = true;
this.lbl_ADC_RPA0.Location = new System.Drawing.Point(38, 66);
this.lbl_ADC_RPA0.Name = "lbl_ADC_RPA0";
this.lbl_ADC_RPA0.Size = new System.Drawing.Size(35, 13);
this.lbl_ADC_RPA0.TabIndex = 2;
this.lbl_ADC_RPA0.Text = "RPA0";
//
// lbl_UART_RPA0
//
this.lbl_UART_RPA0.AutoSize = true;
this.lbl_UART_RPA0.Location = new System.Drawing.Point(37, 65);
this.lbl_UART_RPA0.Name = "lbl_UART_RPA0";
this.lbl_UART_RPA0.Size = new System.Drawing.Size(35, 13);
this.lbl_UART_RPA0.TabIndex = 4;
this.lbl_UART_RPA0.Text = "RPA0";
//
// cb_UART_RPA0
//
this.cb_UART_RPA0.AutoSize = true;
this.cb_UART_RPA0.Location = new System.Drawing.Point(16, 65);
this.cb_UART_RPA0.Name = "cb_UART_RPA0";
this.cb_UART_RPA0.Size = new System.Drawing.Size(15, 14);
this.cb_UART_RPA0.TabIndex = 5;
this.cb_UART_RPA0.UseVisualStyleBackColor = true;
this.cb_UART_RPA0.CheckedChanged += new System.EventHandler(this.cb_UART_RPA0_CheckedChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(758, 429);
this.Controls.Add(this.tabControl1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabControl1.ResumeLayout(false);
this.tpPWM.ResumeLayout(false);
this.tpPWM.PerformLayout();
this.tpUART.ResumeLayout(false);
this.tpUART.PerformLayout();
this.tpADC.ResumeLayout(false);
this.tpADC.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tpPWM;
private System.Windows.Forms.Label lbl_PWM_RPA0;
private System.Windows.Forms.CheckBox cb_PWM_RPA0;
private System.Windows.Forms.TabPage tpUART;
private System.Windows.Forms.TabPage tpADC;
private System.Windows.Forms.Label lbl_ADC_RPA0;
private System.Windows.Forms.CheckBox cb_ADC_RPA0;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.CheckBox cb_UART_RPA0;
private System.Windows.Forms.Label lbl_UART_RPA0;
}
}
I created a new UserControl which only contains a button.
public partial class TooltipButton : UserControl
{
public TooltipButton()
{
InitializeComponent();
}
public new bool Enabled
{
get { return button.Enabled; }
set { button.Enabled = value; }
}
[Category("Appearance")]
[Description("The text displayed by the button.")]
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Bindable(true)]
public override string Text
{
get { return button.Text; }
set { button.Text = value; }
}
[Category("Action")]
[Description("Occurs when the button is clicked.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new event EventHandler Click;
private void button_Click(object sender, EventArgs e)
{
// Bubble event up to parent
Click?.Invoke(this, e);
}
}