ToolTipsFactory

Task-based Tutorial - How to use ToolTips with the Microsoft DataGrid

This article shows, how the ToolTipsFactory tooltips can be used together with the standard grid-control (DataGrid) provided by the Microsoft .NET-Framework. 

The theory - and code-templates - how the tooltip components can be integrated with generic grid-controls has been discussed in the section on "How to use ToolTips with grid-controls". In this section we are going to use this knowledge to integrate an ImageToolTip with the Microsoft DataGrid-control in a real application.

This application (DataGrid1) allows the user to add image-files to a standard DataGrid-control, which lists the complete filename and the size of each file. If the cursor is moved over the grid, the ImageToolTip will pop-up and display the image of the corresponding image-file, as shown in the movie-clip below (please note: The quality of the movie does not reflect the high rendering-quality of the real tooltips):

 

In the following we will have a closer look at the important details in the source code of this sample application. The source-code and the corresponding Visual Studio project for this sample can be found in the "<ToolTipsFactoryHomeDir>.\Samples\DataGrid1"-directory.

Because in this example we only need to know over which grid-row the cursor is hovering, we only need to define an Integer variable at the form-level to keep track of the current row:

Public Class Form1

    Inherits System.Windows.Forms.Form 

    ...

    'Holds the row/column-coordinates of the current cell...

    Private mCurrentRow As Integer = -1

    ...

As we showed in the section on "How to use ToolTips with grid-controls", the whole logic, to keep track of the current mouse-position in terms of grid-coordinates (row/column) and to provide the tooltip with the content of the current grid-element, is located in the MouseEnter, MouseLeave and MouseMove event-handlers. As can be seen from the listings below, this real implementation does not differ much from the generic approach:

Private Sub dgImages_MouseEnter(ByVal sender As Object, _
                                 ByVal e As System.EventArgs) _
                Handles dgImages.MouseEnter

    'Translate the current MousePosition into
   'grid-coordinates (row/column)...
    Dim hit As DataGrid.HitTestInfo
    hit =
Me.dgImages.HitTest(dgImages.PointToClient(dgImages.MousePosition))

   'We just need to preserve the row-index.
    mCurrentRow = hit.Row

   'If the mouse hits a data-row while entering the grid...
  
If mCurrentRow > -1 Then
        '...we can initiate the display of the image in the tooltip.
        'To get the actual image, it has to be loaded from file first.
        'The filename of the image is stored in Column 0 of the grid.
        Me.ImageTT.Start(dgImages, Image _
        .FromFile(dgImages.Item(mCurrentRow, 0)))
  
End If

End Sub

Private Sub dgImages_MouseLeave(ByVal sender As Object, _
                                ByVal e As System.EventArgs) _
                Handles dgImages.MouseLeave

'As soon as the mouse leaves the grid, it can't be
'pointing to a datarow. Therefore we switch it "off"

mCurrentRow = -1

End Sub

Private Sub dgImages_MouseMove(ByVal sender As Object, _
  
                                ByVal e As System.Windows.Forms.MouseEventArgs)
               
Handles dgImages.MouseMove

    'Translate the current MousePosition into
    'grid-coordinates (row/column)...
   Dim hit As DataGrid.HitTestInfo
    hit =
Me.dgImages.HitTest(e.X, e.Y)

 

    'If the mouse did not move on to another row, the image to
    'be displayed in the tooltip is still the same and no further action
    'is required.
   If hit.Row = mCurrentRow Then Exit Sub

    'The cursor crossed the border to another row since the
    'last MouseMove-event. Therefore the new row becomes the
    'current row.

 
   mCurrentRow = hit.Row

    'If the cursor points to no row in the grid (free space)...
  
If hit.Row = -1 Then
  
     '..any previously displayed tooltip has to be switched off.
  
     Me.ImageTT.Reset(dgImages, True)
  
Else
  
     'The cursor points to a normal datarow. Therefore
  
     'we can initiate the display of the image in the tooltip.
  
     'But before the new image is loaded and displayed by the tooltip,
  
     'the tooltip with the previous image should be turned off first.
  
     '(This is not necessary for small images, because they load
  
     'almost instantly, but with large images it is possible that the
  
     'old image is displayed to long over the current row, what can be
  
     'confusing for the user.)
  
     Me.ImageTT.Reset(dgImages, True)
  
     'To get the actual image, it has to be loaded from file first.
  
     'The filename of the image is stored in Column 0 of the grid.
  
     ImageTT.Start(dgImages, Image.FromFile(dgImages.Item(mCurrentRow, 0)))

    End If

End Sub