我正在开发一个旧的.Net 2.0 WinForms项目,需要将一些单元格设置为只读。
我正在阅读DataTable并将其设置为DataSource并正确设置字段类型
生成DataTable和列
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日
上图显示了我要使用的网格,默认情况下会选择所选的选项。
要禁用未选择的选项,因为邮件类型
无法使用这些传送形式答案 0 :(得分:5)
我在一个小样本项目中检查了这个,这对我有用:
// 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);
}
(完成更改后发生火灾并留下电池。)
您可以使用Ivan Stoev 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;
}
}
}
答案 1 :(得分:1)
试试这个
((DataGridViewCheckBoxCell)Rows[Index].Cells["colName"]).ReadOnly = true;
希望它适合你。
答案 2 :(得分:0)
根据我的理解,在填充时,如果复选框的初始值为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;
}
}
}
答案 3 :(得分:0)
修改强>
好的,我意识到小提琴代码不是你的(我应该仔细阅读)。我能够使用您问题中的代码重新创建它。我看到现在的问题,就是这一行:
if(((DataGridViewCheckBoxCell)row.Cells[cell.ColumnIndex]).Selected == false)
您正在测试“已选择”,这不是您想要的,您想要针对单元格的“值”进行测试。
如果你看看其他答案中的代码,这就是他们所展示的内容。
原始答案:留给其他人
运行你的代码(小提琴)复选框确实是只读的,虽然它们看起来没有显示为灰色,就像它们被禁用一样(这是我认为你正在寻找的)你能否确认你是否能够实际检查复选框或不?
很遗憾,您无法直接停用该复选框。
如果这是您想要的,那么您有几个选项,您可以更改单元格的BackColor,这可能就足够了,但这实际上不会改变复选框本身的颜色。
您也可以自己绘制控件,here是类似教程的微软指南。
或者你可以创建一个禁用的单元格,并用它替换你需要的单元格。这不是太多的工作,特别是当someone已经为你完成时!