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