Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WinForms-DataGridViewCell未设置为只读_C#_.net_Winforms - Fatal编程技术网

C# WinForms-DataGridViewCell未设置为只读

C# WinForms-DataGridViewCell未设置为只读,c#,.net,winforms,C#,.net,Winforms,我正在处理一个旧的.NET2.0WinForms项目,需要将一些单元格设置为只读 我有一个数据表,我正在读取并设置为数据源,字段类型设置正确 生成数据表和列 public DataTable FilterData(DataTable datatable, string dataType) { try { if (dataType == "MailPreferences") {

我正在处理一个旧的.NET2.0WinForms项目,需要将一些单元格设置为只读

我有一个数据表,我正在读取并设置为数据源,字段类型设置正确

生成数据表和列

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;
    }
上面的方法在这里被调用,这就是我遇到的禁用细胞的问题

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;
                    }
                }
            }
        }

    }
当逐步浏览并查看Watch窗口时,我可以看到正在设置只读属性,但是当使用DataGridView时,单元格仍然处于活动状态

如果有人能告诉我这段代码哪里错了,或者我需要做些别的事情,我将不胜感激

谢谢你的帮助

---2017年5月31日编辑

上图显示了我想要使用的网格,默认情况下选择的选项是选中的


未选择的选项将被禁用,因为根据我的理解,邮件类型不可能使用这些传递形式。填充时,如果复选框的初始值为false,则应为只读

尝试使用以下命令设置只读值

// not setting the datagridview cell to readonly
foreach (DataGridViewRow row in dgvMailPreferences.Rows) {
    foreach (DataGridViewCell cell in row.Cells) {
        if (cell is DataGridViewCheckBoxCell) {
            DataGridViewCheckBoxCell checkBoxCell = cell as DataGridViewCheckBoxCell;
            //What is the initial  value in the checkbox
            bool isChecked = checkBoxCell.Value as bool;
            //set to read only if not checked
            checkBoxCell.ReadOnly = !isChecked;                 
        }
    }
}

我在一个小样本项目中检查了这一点,这对我很有用:

// 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);
    }
}
此外,您还可以添加事件以跟踪单元格更改,从而为单击的单元格激活只读:

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);
}
(在完成更改并保留单元格后激发。)

您可以从以下位置使用fiddle构建一个示例项目:

试试这个

((DataGridViewCheckBoxCell)Rows[Index].Cells["colName"]).ReadOnly = true;
希望它能对你有用。

编辑:

好吧,我意识到小提琴的代码不是你的(我应该仔细阅读)。我可以用你问题中的代码重新创建这个。我知道问题出在哪里了,是这一行:

if(((DataGridViewCheckBoxCell)row.Cells[cell.ColumnIndex]).Selected == false)
您正在测试的“选定”不是您想要的,您想要测试的是单元格的“值”

如果你看其他答案中的代码,这就是它们所显示的

原始答案:留给他人

运行您的代码(fiddle)复选框确实是只读的,尽管它们不会显示为灰色,好像它们已被禁用(我认为您正在寻找),您能否确认您是否能够实际选中复选框

很遗憾,您不能直接禁用该复选框

如果这是您想要的,那么您有两个选项,您可以更改单元格的背景色,这可能足够了,但是这实际上不会更改复选框本身的颜色

您也可以自己绘制控件,这是一个类似教程的microsoft指南



或者,您可以创建一个禁用的单元格,并用它替换所需的单元格。这不是太多的工作,特别是当你已经为你做了

我对这段代码的解释是,在填充时,它会使当前选中或未选中的所有复选框单元格只读。您表示只希望部分单元格为只读。假设为只读的单元格的条件是什么?在上一个条件中,它必须是
Selected==true
,不是吗?当逐步进行时,我发现这只是使我需要的单元格为只读,使用datagridview并测试是否应禁用复选框时,复选框仍处于活动状态。@anatol否,如果在加载网格时未选中复选框,则将其设置为读取only@SimonPrice您可以尝试将bool列设置为只读,如果这是您想要的。但是,在提供更清晰的细节之前,这只是darkI get中的一个镜头。当查看value==false时,错误运算符“==”不能应用于object和bool类型的操作数。我现在将尝试此操作。仍然是相同的问题,复选框仍然是enabledAll复选框。在调试模式下单步执行代码时,它是否设置了值。@SimonPrice在调用
PopulateMailPreferencesGV()
后是否更改了网格的任何属性,这些属性可能会覆盖正在设置的内容。我将稍后对此进行测试,并让您知道我是如何在HMMM上获得的,我使用了.NET4.0等一下,然后我将其降级到2.0。我用.NET2.0检查了这一点,它仍然有效。您使用哪个VS版本?@SimonPrice如果您将fiddle代码复制到一个新项目中,您将看到它是有效的。不要运行页面上的代码!只需使用.NET 2.0创建一个项目,并将此代码复制到
Program.cs
中,然后运行该项目。事实上,我只是支持这个答案(投票后),因为我认为它是正确的。很高兴看到它得到了赏金(希望问题也得到了解决),很高兴为所有人编码:)是的,我可以确认我能够选中和取消选中应为只读的框。使用此单元格。值而不是单元格。选中了吗?
if(((DataGridViewCheckBoxCell)row.Cells[cell.ColumnIndex]).Selected == false)