在禁用的控件上显示工具提示

当鼠标hover在禁用的控件上时,我正在尝试显示工具提示。 由于禁用的控件不处理任何事件,我必须在父表单中执行此操作。 我选择通过处理父窗体中的MouseMove事件来完成此操作。 这是完成工作的代码:

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

代码确实处理禁用控件的工具提示显示。 问题是当鼠标hover在禁用的控件上时,工具提示会一直关闭并重新显示。 从我在工具提示中添加的显示时间开始,当鼠标位于父窗体上方时, MouseMove事件大约每3秒调用一次,因此工具提示每3秒更新一次。 但是当鼠标在禁用的控件上时,工具提示每1秒刷新一次。 此外,当工具提示在表单上方刷新时,只有文本会通过简短的闪存进行更新。 但是当工具提示在禁用的控件上方刷新时,工具提示窗口会关闭,就像鼠标移动到启用的控件中一样,工具提示应该关闭。 但随后工具提示立即重新出现。

有人能告诉我为什么会这样吗? 谢谢。

当鼠标击中提取的控件时,您只能显示工具提示一次,然后在鼠标离开时隐藏它。 请看下面的代码,它应该显示表单上所有禁用控件的工具提示消息

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

希望这会有所帮助,问候

答案结果有点简单,但需要随时应用。

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

我尝试了很多,但最终使用了这个简单的技巧,我觉得它更有效。

创建一个子类(CustomControl中只包含基本控件),它扩展了UserControl

然后,不是将“Enabled”属性设置为false,而是创建一个方法,该方法仅禁用其中的basecontrol而不是整个CustomControl。

在CustomControl上设置工具提示仍然可以触发事件处理程序设置禁用基本控件。 这适用于使用CustomControl的任何地方,而不是在您使用的每个表单上进行编码。

这是提示…… 🙂

 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 } 

这是我如何解决这个问题

我有一个为PIC32MX自动生成代码的应用程序。

该应用程序有3个标签页文本= PWM,ADC和UART。

在每个标签页上,我有一个复选框文本= RPA0

目的是,当外设使用RPA0时,通过在其他页面上禁用该引脚来阻止其他外设使用该引脚,并且必须在禁用的复选框上弹出工具提示文本(例如“由PWM使用”)外设正在使用该引脚。

问题是工具提示文本不会在禁用的复选框上弹出。

为了解决这个问题,我刚刚删除了复选框和插入标签的文本,复选框应该包含文本。

选中复选框后,其他复选框将被禁用,其旁边的标签将显示工具提示文本。

启用标签后,即使在禁用的复选框上,也会弹出工具提示文本。

工作量增加一倍,复杂性增加一半。

这是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 { ///  /// Required designer variable. ///  private System.ComponentModel.IContainer components = null; ///  /// Clean up any resources being used. ///  /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  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; } } 

我创建了一个新的UserControl,它只包含一个按钮。

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

在TextBox控件的情况下,使其成为readonly解决了问题。