How to change the mouse cursor in WinForms GridDataBoundGrid?
Change the mouse cursor
Description
When you move the mouse cursor over the WinForms 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.

Figure 1: Cursor change in GridControl
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:
Conclusion
I hope you enjoyed learning about how to change the mouse cursor in WinForms GridControl, GridDataBoundGrid and GridGroupingControl.
You can refer to our WinForms Grid Control’s feature tour page to know about its other groundbreaking feature representations. 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 forums, Direct-Trac, or feedback portal. We are always happy to assist you!