Hover ListBox by Seth Willits
06-18-05




Using a New Feature From REALbasic 2005!
In this tutorial, we're going to use a new feature of the ListBox class, the RowFromXY method, which as it is named, returns a row index given an x, y coordinate pair inside of the Listbox's bounds. In this tutorial, we'll use the RowFromXY method to highlight the row the cursor is over, a simple act which in RB 5.5 was more trouble than it was worth.



Let's Begin
First, start off by creating a new ListBox subclass called "HoverListBox". Then add two protected Integer properties, mHoverRow and mLastHoverRow, and add a new method HoverRow which returns an Integer. The HoverRow method will simply return the value of mHoverRow In the Open event of the HoverListBox class set the value of mHoverRow and mLastHoverRow to -1.

Now that the setup is done, we can begin with the real work (if you could call it that). First, the MouseMove event of the HoverRow class should save the previously hovered-over row which is stored in the mHoverRow variable. Then, using the RowFromXY method, the row the mouse cursor is currently hovering over is saved. Both rows are redrawn using the InvalidateCell method, and passing -1 as the column. This redraws all columns in that row.

Sub MouseMove(X As Integer, Y As Integer)  
  
  // Find New Hover Row
  mLastHoverRow = mHoverRow
  mHoverRow = Me.RowFromXY(x, y)
  
  // Redraw Previous Cell
  if mLastHoverRow <> -1 then
    Me.InvalidateCell mLastHoverRow, -1
  end if
  
  // Redraw Current Cell
  if mHoverRow <> -1 then
    Me.InvalidateCell mHoverRow, -1
  end if
  
  
  // Call the Instance Event
  MouseMove X, Y
End Sub


Besides the MouseMove event, we also need to handle the case where the mouse cursor moves outside of the ListBox, since at that point no row will be hovered over.

Sub MouseExit()
  
  // Find New Hover Row
  mLastHoverRow = mHoverRow
  mHoverRow = -1
  
  // Redraw Previous Cell
  if mLastHoverRow <> -1 then
    Me.InvalidateCell mLastHoverRow, -1
  end if  
  
  // Call the Instance Event
  MouseExit
  
End Sub


Before invalidating anything, we first check to see if the row is a valid index. If it weren't, pasing -1, -1 to the InvalidateCell method would redraw the entire ListBox everytime the mouse moved!


Testing It
To test the class, create a new HoverListBox instance in Window1 and then place the code below in the CellBackgroundPaint event as shown.

Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) As Boolean
  if row = me.HoverRow then
    g.ForeColor = HighlightColor
    g.FillRect 0, 0, g.Width, g.Height
  end if
End Function


Finished
All done! As always, you can download the project here.