Articles in this section
Category / Section

How to change the mouse cursor in WinForms GridControl?

5 mins read

Change the mouse cursor

Description

When you move the mouse cursor over the Grid, by default the arrow cursor is displayed. You can change the mouse cursor by using the following three methods.

Solution

You can implement this in three ways,

1. Using CellCursor event.

2. Using OnSetCursor.

3. Using IMouseController interface.

Using CellCursor event

The easiest way to change the cursor for the grid cells is to handle the Gridcontrol's CellCursor event and assign the cursor object to the Cursor property and set e.Cancel to true. This event method is called when the Grid queries, the cursor that is to be displayed for a cell and before the cell renderer returns its cursor. But, also other MouseControllers can take control in cases like ResizingColumns, ResizingRows, and Drag/Drop displaying mouse cursors according to the controllers.

Refer to the following code example for GridControl, GridDataBoundGrid and GridGroupingControl respectively.

GridControl

C#

//CellCursor event triggered.
this.gridControl1.CellCursor +=new GridCellCursorEventHandler(gridControl1_CellCursor);
private void gridControl1_CellCursor(object sender, GridCellCursorEventArgs e)
{
   e.Cursor = Cursors.Hand;
   e.Cancel = true;
}

VB

'CellCursor Event triggered
AddHandler gridControl1.CellCursor, AddressOf gridControl1_CellCursor
Private Sub gridControl1_CellCursor(ByVal sender As Object, ByVal e As GridCellCursorEventArgs)
   e.Cursor = Cursors.Hand
   e.Cancel = True
End Sub

GridDataBoundGrid

C#

// Event triggered from form load.
this.gridDataBoundGrid1.CellCursor +=new GridCellCursorEventHandler(gridDataBoundGrid1_CellCursor);
private void gridDataBoundGrid1_CellCursor(object sender, GridCellCursorEventArgs e)
{
   e.Cursor = Cursors.Hand;
   e.Cancel = true;
}

VB

'Event triggered from form load.
Private Me.gridDataBoundGrid1.CellCursor += New GridCellCursorEventHandler(AddressOf gridDataBoundGrid1_CellCursor)
Private Sub gridDataBoundGrid1_CellCursor(ByVal sender As Object, ByVal e As GridCellCursorEventArgs)
   e.Cursor = Cursors.Hand
   e.Cancel = True
End Sub

GridGroupingControl

C#

//Event Triggered.
this.gridGroupingControl1.TableControl.CellCursor +=new GridCellCursorEventHandler(gridGroupingControl1_CellCursor);
private void gridGroupingControl1_CellCursor(object sender, GridCellCursorEventArgs e)
{
   e.Cursor = Cursors.Hand;
   e.Cancel = true;
}

VB

'Event Triggered.
Private Me.gridGroupingControl1.TableControl.CellCursor += New GridCellCursorEventHandler(AddressOf gridGroupingControl1_CellCursor)
Private Sub gridGroupingControl1_CellCursor(ByVal sender As Object, ByVal e As GridCellCursorEventArgs)
   e.Cursor = Cursors.Hand
   e.Cancel = True
End Sub

Using OnSetCursor()

In this method, derive the Grid and override the OnSetCursor. You can also add additional checks to narrow down as to where you want to set the cursor.

Refer to the following code example for GridControl OnSetCursor method and similarly for GridDataBoundGrid and GridGroupingControl.

C#

public class MyDerivedGridControl : GridControl
{
    public MyDerivedGridControl():base()
    {
        //
        // TODO: Add constructor logic here
        //
    }
    protected override void OnSetCursor(ref System.Windows.Forms.Message m)
    {
       int row;
       int col;
       if(this.PointToRowCol((this.PointToClient(Control.MousePosition)),out row,out col))
       {
          // the cursor has to be added to the project as an embedded resource,
          // and the name you use here as "NameSpace.addedResourcename". It is case sensitive.
          System.IO.Stream stream = this.Parent.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.AqPen.cur");
          if(stream != null)
             Cursor.Current = new Cursor(stream);
          else
             Cursor.Current = Cursors.Hand;
       }
       else
       {
          System.IO.Stream stream = this.Parent.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.NaHand.cur");
          if(stream != null)
             Cursor.Current = new Cursor(stream);
          else
             Cursor.Current = Cursors.Cross;
       }
    }
}

VB

Public Class MyDerivedGridControl
    Inherits GridControl
    Public Sub New()
        MyBase.New()
    '
    ' TODO: Add constructor logic here
    '
    End Sub
    Protected Overrides Sub OnSetCursor(ByRef m As System.Windows.Forms.Message)
       Dim row As Integer
       Dim col As Integer
       If Me.PointToRowCol((Me.PointToClient(Control.MousePosition)),row,col) Then
          ' the cursor has to be added to the project as an embedded resource,
          ' and the name you use here as "NameSpace.addedResourcename" . It is case sensitive.
          Dim stream As System.IO.Stream = Me.Parent.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.AqPen.cur")
          If stream IsNot Nothing Then
             Cursor.Current = New Cursor(stream)
          Else
             Cursor.Current = Cursors.Hand
          End If
       Else
          Dim stream As System.IO.Stream = Me.Parent.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.NaHand.cur")
           If stream IsNot Nothing Then
              Cursor.Current = New Cursor(stream)
           Else
              Cursor.Current = Cursors.Cross
           End If
       End If
    End Sub
End Class

Using IMouseController

In this method, implement the IMouseController interface that allows you to control the cursor, and fit it directly into the grid's mouse controller architecture. This requires more code but, it is not required to derive the Grid. The main method that you handle in this is the HitTest that returns a non-zero hit-test value to indicate the Grid at the point where your mouse controller wants the control.

Refer to the following code example for GridControl IMouseController method and similarly for GridDataBoundGrid and GridGroupingControl.

C#

public class MyMouseController : IMouseController
{
    GridControlBase owner;
    private int lastHitTestCode = GridHitTestContext.None;
    private const int MyMouseHit = 101;
    private Cursor cursor1;
    public MyMouseController(GridControlBase owner)
    {
        this.owner = owner;
    }
    public string Name
    {
        get
        {
            return "MyMouseController";
        }
    }
    public Cursor Cursor
    {
        get
        {
            if(cursor1 == null)
            {
               Control control = owner.Parent;
               while(control.Parent!=null)
                   control = control.Parent;
                   // the cursor has to be added to the project as an embedded resource,
                   // and the name you use here as "NameSpace.addedResourcename". It is case sensitive.
                   System.IO.Stream stream = control.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.NaArrow.cur");
                   if(stream != null)
                      cursor1 = new Cursor(stream);
                   else
                      cursor1 = Cursors.Cross;
              }
              // could check latestHitTestCode here if this controller has
              // different HitTest states. Cursor is called only if
              // previous call to HitTest was successful.
              return cursor1;
        }
    }
    public void MouseDown(MouseEventArgs e)
    {
        if(e.Button == MouseButtons.Left)
        {
           if(e.Clicks == 1)
           {
              MessageBox.Show("You clicked me!","Hi...",MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
           }
        }
    }
    public int HitTest(MouseEventArgs e, IMouseController controller)
    {
        lastHitTestCode = GridHitTestContext.None;
        Point pt = new Point(e.X, e.Y);
        int rowIndex, colIndex;
        owner.PointToRowCol(pt, out rowIndex, out colIndex);
        Rectangle rect = GetBounds(GridRangeInfo.Cell(rowIndex, colIndex));
        //set it to the top half
        rect.Height /= 2;
        if(rect.Contains(pt))
        {
           lastHitTestCode = MyMouseHit;
        }
        return lastHitTestCode;
    }
    //utility method
    Rectangle GetBounds(GridRangeInfo range)
    {
        Rectangle bounds = owner.RangeInfoToRectangle(range, GridRangeOptions.None);
        bounds.Intersect(owner.ClientRectangle);
        //bounds = owner.RectangleToScreen(bounds);
        return bounds;
    }
}

VB

Public Class MyMouseController
    Implements IMouseController
    Private owner As GridControlBase
    Private lastHitTestCode As Integer = GridHitTestContext.None
    Private Const MyMouseHit As Integer = 101
    Private cursor1 As Cursor
    Public Sub New(ByVal owner As GridControlBase)
        Me.owner = owner
    End Sub
    Public ReadOnly Property Name() As String
        Get
            Return "MyMouseController"
        End Get
    End Property
    Public ReadOnly Property Cursor() As Cursor
        Get
            If cursor1 Is Nothing Then
               Dim control As Control = owner.Parent
               Do While control.Parent IsNot Nothing
                   control = control.Parent
               Loop
               ' the cursor has to be added to the project as an embedded resource,
               ' and the name you use here as "NameSpace.addedResourcename". It is case sensitive.
               Dim stream As System.IO.Stream = control.GetType().Module.Assembly.GetManifestResourceStream("ChangeCursor_CS.NaArrow.cur")
               If stream IsNot Nothing Then
                  cursor1 = New Cursor(stream)
               Else
                  cursor1 = Cursors.Cross
               End If
            End If
            ' could check latestHitTestCode here if this controller has
            ' different HitTest states. Cursor is called only if
            ' previous call to HitTest was successful.
            Return cursor1
        End Get
    End Property
    Public Sub MouseDown(ByVal e As MouseEventArgs)
        If e.Button = MouseButtons.Left Then
           If e.Clicks = 1 Then
              MessageBox.Show("You clicked me!","Hi...",MessageBoxButtons.OK,MessageBoxIcon.Asterisk)
           End If
        End If
    End Sub
    Public Function HitTest(ByVal e As MouseEventArgs, ByVal controller As IMouseController) As Integer
        lastHitTestCode = GridHitTestContext.None
        Dim pt As New Point(e.X, e.Y)
        Dim rowIndex, colIndex As Integer
        owner.PointToRowCol(pt, rowIndex, colIndex)
        Dim rect As Rectangle = GetBounds(GridRangeInfo.Cell(rowIndex, colIndex))
        'set it to the top half
        rect.Height \= 2
        If rect.Contains(pt) Then
           lastHitTestCode = MyMouseHit
        End If
        Return lastHitTestCode
    End Function
    'utility method
    Private Function GetBounds(ByVal range As GridRangeInfo) As Rectangle
       Dim bounds As Rectangle = owner.RangeInfoToRectangle(range, GridRangeOptions.None)
       bounds.Intersect(owner.ClientRectangle)
       'bounds = owner.RectangleToScreen(bounds);
       Return bounds
    End Function
End Class

The following screenshot illustrates the output.

Show cursor changes in GridControl

Figure 1: Cursor change in GridControl

Note:

In the above screenshot, you can see the mouse cursor changed while hovering on GridControl and a similar output arrives for both GridDataBoundGrid and GridGroupingControl.

Samples:

C#: ChangedMouseCursor-C#.

VB: ChangedMouseCursor-VB



Conclusion

You can refer to our WinForms Grid Control’s feature tour page to know about its other groundbreaking feature representation.

You can also explore our WinForms Grid Control documentation to understand how to present and manipulate data.

For current customers, you can check out our WinForms components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our WinForms Grid Control and other WinForms components.

If you have any queries or require clarifications, please let us know in comments below. You can also contact us through our support forumsDirect-Trac, or feedback portal. We are always happy to assist you!

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied