ToolTipListBox.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // written by Mehul Dhorda https://www.codeproject.com/Articles/457444/Listbox-Control-with-Tooltip-for-Each-Item
  2. // licensed under CPOL
  3. using System;
  4. using System.Windows.Forms;
  5. namespace FastReport.Controls
  6. {
  7. internal class ListBoxItem : IToolTipDisplayer
  8. {
  9. public string DisplayText { get; }
  10. public string ToolTipText { get; }
  11. public ListBoxItem(string displayText, string toolTipText)
  12. {
  13. DisplayText = displayText;
  14. ToolTipText = toolTipText;
  15. }
  16. public override string ToString() => DisplayText;
  17. public string GetToolTipText() => ToolTipText;
  18. }
  19. internal interface IToolTipDisplayer
  20. {
  21. string GetToolTipText();
  22. }
  23. internal class ToolTipListBox : ListBox
  24. {
  25. // The item index that the mouse is currently over
  26. private int _currentItem;
  27. // A value indicating if the current item has been set
  28. private bool _currentItemSet;
  29. // A value indicating if a tooltip is currently being displayed
  30. private bool _toolTipDisplayed;
  31. // Timer that is used to wait for the mouse to hover over an item
  32. private Timer _toolTipDisplayTimer;
  33. // Tooltip control
  34. private ToolTip _toolTip;
  35. protected override void OnMouseMove(MouseEventArgs e)
  36. {
  37. base.OnMouseMove(e);
  38. int itemIndex = this.IndexFromPoint(e.Location);
  39. if (itemIndex == ListBox.NoMatches)
  40. {
  41. // Mouse is over empty space in the listbox so hide tooltip
  42. _toolTip.Hide(this);
  43. _currentItemSet = false;
  44. _toolTipDisplayed = false;
  45. _toolTipDisplayTimer.Stop();
  46. }
  47. else if (!_currentItemSet)
  48. {
  49. // Mouse is over a new item so start timer to display tooltip
  50. _currentItem = itemIndex;
  51. _currentItemSet = true;
  52. _toolTipDisplayTimer.Start();
  53. }
  54. else if (itemIndex != _currentItem)
  55. {
  56. // Mouse is over a different item so hide tooltip and restart timer
  57. _currentItem = itemIndex;
  58. _toolTipDisplayTimer.Stop();
  59. _toolTipDisplayTimer.Start();
  60. _toolTip.Hide(this);
  61. _toolTipDisplayed = false;
  62. }
  63. }
  64. protected override void OnMouseLeave(EventArgs e)
  65. {
  66. base.OnMouseLeave(e);
  67. // Mouse has left listbox so stop timer (tooltip is automatically hidden)
  68. _currentItemSet = false;
  69. _toolTipDisplayed = false;
  70. _toolTipDisplayTimer.Stop();
  71. }
  72. private void _toolTipDisplayTimer_Tick(object sender, EventArgs e)
  73. {
  74. // Display tooltip text since the mouse has hovered over an item
  75. if (!_toolTipDisplayed && _currentItem != ListBox.NoMatches &&
  76. _currentItem < this.Items.Count)
  77. {
  78. IToolTipDisplayer toolTipDisplayer = this.Items[_currentItem] as IToolTipDisplayer;
  79. if (toolTipDisplayer != null)
  80. {
  81. _toolTip.SetToolTip(this, toolTipDisplayer.GetToolTipText());
  82. _toolTipDisplayed = true;
  83. }
  84. }
  85. }
  86. public ToolTipListBox()
  87. {
  88. _currentItemSet = false;
  89. _toolTipDisplayed = false;
  90. _toolTipDisplayTimer = new Timer();
  91. _toolTip = new ToolTip();
  92. // Set the timer interval to the system time that it takes for a tooltip to appear
  93. _toolTipDisplayTimer.Interval = SystemInformation.MouseHoverTime;
  94. _toolTipDisplayTimer.Tick += _toolTipDisplayTimer_Tick;
  95. }
  96. }
  97. }