This blog is part of the utility implementation of C1FlexGrid for Winforms. As theĀ  title suggests, we will be avoiding setting the focus on cells marked as ReadOnly through tab movement, mouse click, or code. Any kind of action setting the focus on ReadOnly cells moves the focus to the next or previous editable cell.

Lets quickly start with the implementation section.

Setting ReadOnly cells

C1FlexGrid does not have a feature that directly sets a cell as ReadOnly, and in order to do so, we have to ‘tag’ the cell as ReadOnly. We can set the value of ‘UserData’ property of the cell as ‘Locked.’ We can later use this property to determine if the cell is marked as ReadOnly.

' Maintains the list of non editable cells
Public noneditablelist As New List(Of C1.Win.C1FlexGrid.CellRange)

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    flex.Cols.Count = 6
    flex.Rows.Count = 10

    flex.KeyActionTab = C1.Win.C1FlexGrid.KeyActionEnum.MoveAcrossOut
    flex.KeyActionEnter = C1.Win.C1FlexGrid.KeyActionEnum.MoveAcrossOut

    noneditablelist.Add(flex.GetCellRange(1, 2))
    noneditablelist.Add(flex.GetCellRange(1, 4))
    noneditablelist.Add(flex.GetCellRange(2, 2))
    noneditablelist.Add(flex.GetCellRange(3, 3))
    noneditablelist.Add(flex.GetCellRange(3, 5))
    noneditablelist.Add(flex.GetCellRange(5, 4))
    noneditablelist.Add(flex.GetCellRange(4, 3))
    noneditablelist.Add(flex.GetCellRange(6, 2))
    noneditablelist.Add(flex.GetCellRange(4, 1))

    ' Marks Tag for each non editable cell as Locked and
    ' change back color

    For Each lc As C1.Win.C1FlexGrid.CellRange In noneditablelist
       lc.StyleNew.BackColor = Color.LightGreen
       flex.SetUserData(lc.r1, lc.c1, "Locked")
    Next

End Sub

Set focus on Next/Previous Editable Cell

This section of code determines which cell will receive the focus when focus is changed using Tab, Enter, Direction keys, or mouse. BeforeSelChange() event is used for all the code execution.

' Variable to be used for determining Cell Change
Dim allowmove As Boolean = False
Private Sub flex_BeforeSelChange(sender As Object, e As C1.Win.C1FlexGrid.RangeEventArgs) Handles flex.BeforeSelChange

        If allowmove = True Then
            allowmove = False
            Exit Sub
        End If

        Dim row As Integer = e.NewRange.r1
        Dim col As Integer = e.NewRange.c1

        While Not allowmove

            If flex.GetUserData(row, col) = "Locked" Then

                ' if the current Column is ReadOnly,
                ' increase the Column index to next Column or previous Column
                If e.NewRange.r1 > e.OldRange.r1 Then
                    col += 1
                ElseIf e.NewRange.r1 < e.OldRange.r1 Then
                    col -= 1
                Else
                    If e.NewRange.c1 >= e.OldRange.c1 Then
                        col += 1
                    Else
                        col -= 1
                    End If
                End If

                ' Reposition the Focus to next Row, if Col is equal to last column of the Grid.
                If col >= flex.Cols.Count Then

                    ' Reposition the Row to 1st Row if 'Row' is equal to last row of the Grid.
                    If row = flex.Rows.Count - 1 Then
                        row = flex.Rows.Fixed
                    Else
                        row += 1
                    End If
                    col = flex.Cols.Fixed
                    ' Reposition the Focus to previous Row, if Col is equal to fixed columns of the Grid.
                ElseIf col <= flex.Cols.Fixed - 1 Then
                    row -= 1
                    col = flex.Cols.Count - 1
                End If

            Else
                allowmove = True
            End If
        End While

        ' Cancel the default Row Movement
        e.Cancel = True

        ' Move focus to the next Editable Cell
        flex.Select(row, col)

    End Sub

Once you have the above code implemented correctly, cells marked as ReadOnly will not receive the focus. However, if you double click on these cells, they get into edit mode. Thus, we have to supress the double click action on these cells.

    ' Cancel double click event on non editable cells
    Private Sub flex_BeforeDoubleClick(sender As Object, e As C1.Win.C1FlexGrid.BeforeMouseDownEventArgs) Handles flex.BeforeDoubleClick
        Dim hti As C1.Win.C1FlexGrid.HitTestInfo = flex.HitTest(e.X, e.Y)
        If noneditablelist.Contains(flex.GetCellRange(hti.Row, hti.Column)) Then
            e.Cancel = True
        End If
    End Sub

You can download the complete sample from the given link.

Download Sample

Tags: , ,