Search code examples
c#winformsdatagridviewdatagridviewcolumndatagridviewrow

How can I make a cell to read only when it has been filled? DataGridView C#


I want to have a table displayed on a DataGridView with multiple columns, all of them on readonly but one. This one column needs to have the capacity of being filled by the user, but I want to make the cells that already have content on them ReadOnly, not all the column so the user will still have the capacity of fill the remaining cells on the column (with the exception of the ones that already have been filled)

Is there a way to achieve this?


Solution

  • You can set CellEndEdit event simply like this:

    private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        DataGridViewCell cell =        this.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex);
        cell.ReadOnly = true;
    }
    

    VB.NET:

    Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
        Dim cell As DataGridViewCell = Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
        cell.ReadOnly = True
    End Sub
    

    And if you have data in the DataGridView at the beginning, you can set the access after you load the data like this:

    SetAccess(this.DataGridView1);
    

    VB.NET:

    Call SetAccess(Me.DataGridView1)
    

    ...providing this function in your class:

    private void SetAccess(DataGridView dgw)
    {
        for (var ir = 0; ir <= dgw.Rows.Count - 1; ir++)
        {
            for (var ic = 0; ic <= dgw.Columns.Count - 1; ic++)
            {
                DataGridViewCell cell = this.DataGridView1.Rows(ir).Cells(ic);
                if (!IsNothing(cell.Value) && cell.Value.ToString.Length > 0)
                    cell.ReadOnly = true;
            }
        }
    }
    

    VB.NET:

    Private Sub SetAccess(dgw As DataGridView)
        For ir = 0 To dgw.Rows.Count - 1
            For ic = 0 To dgw.Columns.Count - 1
                Dim cell As DataGridViewCell = Me.DataGridView1.Rows(ir).Cells(ic)
                If Not IsNothing(cell.Value) AndAlso cell.Value.ToString.Length > 0 Then
                    cell.ReadOnly = True
                End If
            Next
        Next
    End Sub
    

    Tested, all works as a charm.

    Obviously you can play with the code, i.e. excluding the last column by modifying the range of column loop:

    For ic = 0 To dgw.Columns.Count - 2
    

    VB.NET (same):

    For ic = 0 To dgw.Columns.Count - 2
    

    Sorry, missed the c# tag when replied first.