以编程方式更改DataGridView行的只读模式

6

不解释整个背景,我的问题基本上是这样的:

我在Windows窗体上有一个datagridview,它绑定到一个Entity Framework DbSet:dbSet<TEntity>.Local.ToBindingList()

如果我将datagridview的ReadOnly属性设置为true(在设计视图中),然后在我的代码中有以下语句:

  myDataGridView.Rows[rowIndex].ReadOnly = false;

它直接通过而不改变值!(并且,我的数据源不是只读的。)

循环遍历行中的单元格并逐个设置每个单元格的ReadOnly属性也不起作用:

  foreach (DataGridViewCell cell in myDataGridView.Rows[rowIndex].Cells)
  {
      cell.ReadOnly = false;
  }

.ReadOnly - 获取或设置一个值,指示用户是否可以编辑DataGridView控件的单元格。 但它好像由于某些原因无法设置

这可能是什么原因呢?我认为可能是datagridview的ReadOnly属性会覆盖对特定行/单元格所做的任何更改(即整个表单必须是只读的或不可读的),但显然这种情况对某人起作用...

有其他方法可以达到我的目标,但我想知道为什么无法更改此属性,因为这将是我情况下最简单的解决方案。


编辑:

让我尝试澄清一下我的问题:

再次说明,我知道有其他方法可以达到我的目标,但我想回答这个问题:

很抱歉,这样的例子太简单了,但要轻松复制该问题,请创建一个WinForm应用程序,在其中添加一个datagridview,并将此代码粘贴到您的项目中:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.ReadOnly = true;
        string[] row1 = new string[] { "test", "test1" };
        string[] row2 = new string[] { "test2", "test3" };
        string[] row3 = new string[] { "test4", "test5" };
        dataGridView1.Columns.Add("1", "1");
        dataGridView1.Columns.Add("2", "2");
        dataGridView1.Rows.Add(row1);
        dataGridView1.Rows.Add(row2);
        dataGridView1.Rows.Add(row3);

        dataGridView1.Rows[1].ReadOnly = false;
    }
}

如果您在最后一行设置断点并逐步执行,您会发现ReadOnly属性没有改变!为什么?

你的code-behind代码何时运行?GridView的ReadOnly属性何时被设置为true?你确定它们的发生顺序正确吗? - Melanie
@Melanie 我在设计视图中将 GridView 的 ReadOnly 属性设置为 true(而不是在运行时)。代码在 buttonClick 事件上运行。 - sǝɯɐſ
那么buttonClick事件会导致postback,是吗?也许如果你在PageLoad()中将GridView的ReadOnly属性设置为true呢? - Melanie
@spajce 你好,你说得对,我正在使用带有DbContext的EF...如果我没有表述清楚,对不起...我认为EF与我的问题无关,我只是想提供一些背景资料...或者也许它确实有关系?此外,我不太确定你所说的“默认情况下DataGridView列属性设置为false”是什么意思? - sǝɯɐſ
抱歉,我的意思是默认情况下DataGridView Columnreadonly=false。无论如何,关于你的问题,你能分享一下你是如何使用这个的吗?是用dbSet<TEntity>.Local.ToBindingList()还是整个代码? - spajce
显示剩余11条评论
1个回答

7

我已经找到了一个解决方案/解决办法,虽然我仍然不确定原因为何...

显然,如果你想逐行更改DataGridView的只读属性,你不能设置主要的DataGridView.ReadOnly属性,因为这显然会覆盖任何后续更改。

重复使用之前的示例,解决方法是循环遍历每一行并设置每个ROW的ReadOnly属性(而不是设置datagridview的ReadOnly属性),然后你可以逐个更改每一行的ReadOnly属性:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //dataGridView1.ReadOnly = true;
        string[] row1 = new string[] { "test", "test1" };
        string[] row2 = new string[] { "test2", "test3" };
        string[] row3 = new string[] { "test4", "test5" };
        dataGridView1.Columns.Add("1", "1");
        dataGridView1.Columns.Add("2", "2");
        dataGridView1.Rows.Add(row1);
        dataGridView1.Rows.Add(row2);
        dataGridView1.Rows.Add(row3);

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            row.ReadOnly = true;
        }

        dataGridView1.Rows[1].ReadOnly = false;
    }
}

这对我来说非常有效,但是如果您能提供关于为什么我的原始问题中的代码无法正常工作的任何见解,将不胜感激!


这应该被接受为答案。实际上可能并没有太多意义,但我遇到了同样的问题并逐个设置(在我这里是列)使它们正确地运行。 - aliceraunsbaek
@aliceraunsbaek,很高兴能帮到你!我会将其标记为答案,除非有人发布更好的解决方案... - sǝɯɐſ
1
如果你想知道为什么,那可能是由于层次结构和.NET采取最快的路线。它看到整个视图都设置为ReadOnly = true,并且不使用资源进一步检查对象。这种更高级别的设置会覆盖较低级别的设置。 - VenerableAgents
@VenerableAgents 对我来说听起来很合理...太遗憾了,.NET 不能再聪明一些,但我能理解为什么它会以这种方式进行检查以节省时间/资源...谢谢你的见识! - sǝɯɐſ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接