2

我正在显示一个小工具提示,但如果我更改下拉菜单中的选定项/文本,工具提示会显示旧文本和新文本。我希望它只显示新文本。

private void optionsvalueComboBox_MouseHover(object sender, EventArgs e)
{
    ToolTip buttonToolTip = new ToolTip();
    buttonToolTip.ToolTipTitle = "Value";
    buttonToolTip.UseFading = true;
    buttonToolTip.UseAnimation = true;
    buttonToolTip.IsBalloon = true;
    buttonToolTip.ShowAlways = true;
    buttonToolTip.AutoPopDelay = 5000;
    buttonToolTip.InitialDelay = 1000;
    buttonToolTip.ReshowDelay = 0;

    buttonToolTip.SetToolTip(optionsvalueComboBox, optionsvalueComboBox.Text);
}
4

3 回答 3

7

假设您不喜欢工具提示文本从旧文本更改为新文本...

这样做的原因是因为您要在每个悬停事件上创建一个新的工具提示实例。每次触发悬停事件时,旧的工具提示实例都会被新的工具提示实例替换,这就是您同时看到两者的原因。要解决此问题,请将声明放在事件之外,如下所示:

ToolTip buttonToolTip = new ToolTip();

private void optionsvalueComboBox_MouseHover(object sender, EventArgs e)
{
    buttonToolTip.ToolTipTitle = "Value";
    buttonToolTip.UseFading = true;
    buttonToolTip.UseAnimation = true;
    buttonToolTip.IsBalloon = true;
    buttonToolTip.ShowAlways = true;
    buttonToolTip.AutoPopDelay = 5000;
    buttonToolTip.InitialDelay = 1000;
    buttonToolTip.ReshowDelay = 0;

    buttonToolTip.SetToolTip(optionsvalueComboBox, optionsvalueComboBox.Text);
  }

现在使用相同的工具提示,只是替换了措辞。让我知道这是否适合您!

于 2013-10-30T17:26:09.680 回答
3

我已经尝试在MouseHover发生 a的情况下进行挖掘,ComboBox并且看起来它不像我们预期的那样正常工作。MouseHover实际上,只有当您将鼠标移到if 您的样式为时才会触发。最简单的解决方案是将您的组合框样式更改为:drop down buttonComboBoxdropdowndropdownlist

comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;

然而,这种风格会使ComboBox只读。如果这不是您想要的,有一个解决方法是使用MouseMove带有 a的事件Timer来模仿MouseHover,这是适合您的代码:

public partial class Form1 : Form {
  public Form1(){
    InitializeComponent();
     t.Interval = 600;
     t.Tick += (se, ev) => {
       buttonToolTip.SetToolTip(comboBox1, (string)comboBox1.SelectedItem);
       t.Stop();
     };
     //init the buttonToolTip
     buttonToolTip.ToolTipTitle = "Value";
     buttonToolTip.UseFading = true;
     buttonToolTip.UseAnimation = true;
     buttonToolTip.IsBalloon = true;
     buttonToolTip.ShowAlways = true;
     buttonToolTip.AutoPopDelay = 5000;
     buttonToolTip.InitialDelay = 1000;
     buttonToolTip.ReshowDelay = 0;
     //register MouseMove event handler for your comboBox1
     comboBox1.MouseMove += (se, ev) => {                    
       //Restart the timer every time the mouse is moving
       t.Stop();
       t.Start();
     };
  }
  Timer t = new Timer();
  ToolTip buttonToolTip = new ToolTip();
}
于 2013-10-30T17:40:41.200 回答
2

一个完整的工作示例:

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public RECT(Rectangle rect)
    {
        Left = rect.Left;
        Top = rect.Top;
        Right = rect.Right;
        Bottom = rect.Bottom;
    }

    public Rectangle Rect
    {
        get
        {
            return new Rectangle(Left, Top, Right - Left, Bottom - Top);
        }
    }

    public Point Location
    {
        get
        {
            return new Point(Left, Top);
        }
    }

    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

public class ToolTipComboBox: ComboBox
{
    #region Fields

    private ToolTip toolTip;
    private bool _tooltipVisible;
    private bool _dropDownOpen;
    #endregion

    #region Types

    [StructLayout(LayoutKind.Sequential)]
    // ReSharper disable once InconsistentNaming
    public struct COMBOBOXINFO
    {
        public Int32 cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public ComboBoxButtonState buttonState;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
    }

    public enum ComboBoxButtonState
    {
        // ReSharper disable once UnusedMember.Global
        StateSystemNone = 0,
        // ReSharper disable once UnusedMember.Global
        StateSystemInvisible = 0x00008000,
        // ReSharper disable once UnusedMember.Global
        StateSystemPressed = 0x00000008
    }

    [DllImport("user32.dll")]
    public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

    #endregion

    #region Properties

    private IntPtr HwndCombo
    {
        get
        {
            COMBOBOXINFO pcbi = new COMBOBOXINFO();
            pcbi.cbSize = Marshal.SizeOf(pcbi);
            GetComboBoxInfo(Handle, ref pcbi);
            return pcbi.hwndCombo;
        }
    }

    private IntPtr HwndDropDown
    {
        get
        {
            COMBOBOXINFO pcbi = new COMBOBOXINFO();
            pcbi.cbSize = Marshal.SizeOf(pcbi);
            GetComboBoxInfo(Handle, ref pcbi);
            return pcbi.hwndList;
        }
    }

    [Browsable(false)]
    public new DrawMode DrawMode
    {
        get { return base.DrawMode; }
        set { base.DrawMode = value; }
    }

    #endregion

    #region ctor

    public ToolTipComboBox()
    {
        toolTip = new ToolTip
        {
            UseAnimation = false,
            UseFading = false
        };

        base.DrawMode = DrawMode.OwnerDrawFixed;
        DrawItem += OnDrawItem;
        DropDownClosed += OnDropDownClosed;
        DropDown += OnDropDown;
        MouseLeave += OnMouseLeave;
    }

    #endregion

    #region Methods

    private void OnDropDown(object sender, EventArgs e)
    {
        _dropDownOpen = true;
    }

    private void OnMouseLeave(object sender, EventArgs e)
    {
        ResetToolTip();
    }

    private void ShowToolTip(string text, int x, int y)
    {
        toolTip.Show(text, this, x, y);
        _tooltipVisible = true;
    }

    private void OnDrawItem(object sender, DrawItemEventArgs e)
    {
        ComboBox cbo = sender as ComboBox;
        if (e.Index == -1) return;

        // ReSharper disable once PossibleNullReferenceException
        string text = cbo.GetItemText(cbo.Items[e.Index]);
        e.DrawBackground();

        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        {
            TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds.Location, SystemColors.Window);

            if (_dropDownOpen)
            {
                Size szText = TextRenderer.MeasureText(text, cbo.Font);
                if (szText.Width > cbo.Width - SystemInformation.VerticalScrollBarWidth && !_tooltipVisible)
                {
                    RECT rcDropDown;
                    GetWindowRect(HwndDropDown, out rcDropDown);

                    RECT rcCombo;
                    GetWindowRect(HwndCombo, out rcCombo);

                    if (rcCombo.Top > rcDropDown.Top)
                    {
                        ShowToolTip(text, e.Bounds.X, e.Bounds.Y - rcDropDown.Rect.Height - cbo.ItemHeight - 5);
                    }
                    else
                    {
                        ShowToolTip(text, e.Bounds.X, e.Bounds.Y + cbo.ItemHeight - cbo.ItemHeight);
                    }
                }
            }
        }
        else
        {
            ResetToolTip();
            TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds.Location, cbo.ForeColor);
        }

        e.DrawFocusRectangle();
    }

    private void OnDropDownClosed(object sender, EventArgs e)
    {
        _dropDownOpen = false;
        ResetToolTip();
    }

    private void ResetToolTip()
    {
        if (_tooltipVisible)
        {
            // ReSharper disable once AssignNullToNotNullAttribute
            toolTip.SetToolTip(this, null);
            _tooltipVisible = false;
        }
    }

    #endregion
}
于 2016-06-09T23:02:20.270 回答