How to change the mouse cursor in WinForms GridControl?
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.
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
You can refer to our WinForms Grid Control’s feature tour page to know about its other groundbreaking feature representation.
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!