Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinForms - DataGridViewCell not being set to read only

Tags:

c#

.net

winforms

I am working on an old .Net 2.0 WinForms project and need to set some cells to read only.

I have a DataTable that I am reading and setting as the DataSource and the field types are being set correctly

Generate DataTable and columns

public DataTable FilterData(DataTable datatable, string dataType)
    {
        try
        {
            if (dataType == "MailPreferences")
            {

                var dt = new DataTable();

                dt.Columns.Add("SEQ_ID", typeof(int));                              // SEQ_ID
                dt.Columns.Add("MAIL_PREFERENCE_ID", typeof(string));               // MAIL_PREFERENCE_ID
                dt.Columns.Add("Mail Preference Description", typeof(string));      // MAIL_PREFERENCE_DESC
                dt.Columns.Add("Post", typeof(bool));                               // POST
                dt.Columns.Add("SMS", typeof(bool));                                // SMS
                dt.Columns.Add("Email", typeof(bool));                              // EMAIL
                dt.Columns.Add("Telephone", typeof(bool));                          // TELEPHONE

                foreach (DataRow row in datatable.Rows)
                {
                    dt.Rows.Add(row["SEQ_ID"].ToString(), 
                                row["MAIL_PREFERENCE_ID"].ToString(), 
                                row["MAIL_PREFERENCE_DESC"].ToString(),
                                Convert.ToBoolean(row["POST"]), 
                                Convert.ToBoolean(row["SMS"]), 
                                Convert.ToBoolean(row["EMAIL"]),
                                Convert.ToBoolean(row["TELEPHONE"]));
                }

                return dt;

            }


        }
        catch (Exception ex)
        {
            // catch and deal with my exception here
        }

        return null;
    }

The above method is being called here and this is where I am having the issue of disabling cells.

private void PopulateMailPreferencesGV()
    {
        var dt = FilterData(_cAddPersonWizard.GetMailPreferneces(), "MailPreferences");
        dgvMailPreferences.DataSource = dt;

        dgvMailPreferences.Columns["Mail Preference Description"].Width = 250;
        dgvMailPreferences.Columns["Post"].Width = 50;
        dgvMailPreferences.Columns["SMS"].Width = 50;
        dgvMailPreferences.Columns["Email"].Width = 50;
        dgvMailPreferences.Columns["Telephone"].Width = 75;

        dgvMailPreferences.Columns["SEQ_ID"].Visible = false;
        dgvMailPreferences.Columns["MAIL_PREFERENCE_ID"].Visible = false;


        // not setting the datagridview cell to readonly
        foreach (DataGridViewRow row in dgvMailPreferences.Rows)
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                if (cell.GetType() == typeof(DataGridViewCheckBoxCell))
                {
                    if(((DataGridViewCheckBoxCell)row.Cells[cell.ColumnIndex]).Selected == false)
                    {
                        ((DataGridViewCheckBoxCell)row.Cells[cell.ColumnIndex]).ReadOnly = true;
                    }
                }
            }
        }

    }

When stepping through and looking at the Watch window I can see that the read only properties are being set, however when coming to work with the DataGridView the cells are still active.

I would be grateful if someone could point me in the direction of where this code is wrong or if I need to do something else?

Thanks for your help.

--- Edit 31/05/2017

enter image description here

The image above shows the grid that I want to work with, the options that are selected are selected by default.

The options that are not selected are to be disabled because these forms of delivery are not possible for the mail type

like image 642
Simon Price Avatar asked May 15 '17 09:05

Simon Price


People also ask

How do I make datagrid read-only?

To make a column read-only programmaticallySet the DataGridViewColumn. ReadOnly property to true .

How to Make DataGridView cell ReadOnly in c#?

The ReadOnly property indicates whether the data displayed by the cell can be edited. You can set ReadOnly for individual cells, or you can make an entire row or column of cells read-only by setting the DataGridViewRow. ReadOnly or DataGridViewColumn. ReadOnly properties.

What will happen if the value of the ReadOnly property of the DataGridView is set as true?

A cell is read-only if the value of the ReadOnly property is true for the cell, the cell's row, the cell's column, or the DataGridView.


1 Answers

I had checked this in a small sample project and this worked for me:

// Loop through all the rows of your grid
foreach (DataGridViewRow row in this.dgvMailPreferences.Rows)
{
    // Loop through all the cells of the row
    foreach (DataGridViewCell cell in row.Cells)
    {
        // Check if the cell type is CheckBoxCell
        // If not, check the next cell
        if (!(cell is DataGridViewCheckBoxCell)) continue;

        // Set the specific cell to read only, if the cell is not checked
        cell.ReadOnly = !Convert.ToBoolean(cell.Value);
    }
}

Further you can add an event to track cell changes to activate read only for clicked cells:

private void dgvMailPreferences_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (!(e.RowIndex >= 0 && e.ColumnIndex >= 0)) return;

    DataGridViewCell cell = ((DataGridView)sender).Rows[e.RowIndex].Cells[e.ColumnIndex];

    if (!(cell is DataGridViewCheckBoxCell)) return;

    cell.ReadOnly = !System.Convert.ToBoolean(cell.Value);
}

(Fires after a change was done and the cell was left.)

You can build a sample project with the fiddle from Ivan Stoev at Dotnetfiddle

using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;

namespace Samples
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form();
            var dgv = new DataGridView { Dock = DockStyle.Fill, Parent = form };
            form.Load += (sender, e) =>
            {
                var dt = GetData();
                dgv.DataSource = dt;
                dgv.Columns["Mail Preference Description"].Width = 250;
                dgv.Columns["Post"].Width = 50;
                dgv.Columns["SMS"].Width = 50;
                dgv.Columns["Email"].Width = 50;
                dgv.Columns["Telephone"].Width = 75;
                dgv.Columns["SEQ_ID"].Visible = false;
                dgv.Columns["MAIL_PREFERENCE_ID"].Visible = false;
                foreach (DataGridViewRow row in dgv.Rows)
                {
                    foreach (DataGridViewCell cell in row.Cells)
                    {
                        if (cell.Value is bool && (bool)cell.Value == false)
                            cell.ReadOnly = true;
                    }
                }
            };
            Application.Run(form);
        }

        static DataTable GetData()
        {
            var dt = new DataTable();
            dt.Columns.Add("SEQ_ID", typeof(int));                              // SEQ_ID
            dt.Columns.Add("MAIL_PREFERENCE_ID", typeof(string));               // MAIL_PREFERENCE_ID
            dt.Columns.Add("Mail Preference Description", typeof(string));      // MAIL_PREFERENCE_DESC
            dt.Columns.Add("Post", typeof(bool));                               // POST
            dt.Columns.Add("SMS", typeof(bool));                                // SMS
            dt.Columns.Add("Email", typeof(bool));                              // EMAIL
            dt.Columns.Add("Telephone", typeof(bool));                          // TELEPHONE

            dt.Rows.Add(1, "1", "Membership", true, true, true, true);
            dt.Rows.Add(2, "2", "Monthly Newsletter", false, false, true, false);
            dt.Rows.Add(3, "3", "Mothhly Technical Briefing", false, false, true, false);
            dt.Rows.Add(4, "4", "Magazine", false, false, true, false);
            dt.Rows.Add(5, "5", "Branch Mailings", false, true, true, false);
            dt.Rows.Add(6, "6", "Events", true, true, true, true);
            dt.Rows.Add(7, "7", "Qualifications", true, true, true, true);
            dt.Rows.Add(8, "8", "Training", true, true, true, true);
            dt.Rows.Add(9, "9", "Recruitment", true, true, true, true);
            dt.Rows.Add(10, "A", "General", true, true, true, true);

            return dt;
        }
    }
}
like image 93
Nik Bo Avatar answered Nov 11 '22 22:11

Nik Bo