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

C# 以编程方式更改DataGridView行的只读模式,c#,winforms,datagridview,readonly,C#,Winforms,Datagridview,Readonly,如果不解释整个背景,我的问题基本上是: 我在Windows窗体上有一个datagridview,它绑定到实体框架DbSet:DbSet.Local.ToBindingList() 如果我将datagridview的ReadOnly属性设置为true(在设计视图中),然后在代码中使用以下语句: myDataGridView.Rows[rowIndex].ReadOnly = false; 它一步一步地完成,而不改变值!(不,我的数据源不是只读的。) 在行中的单元格中循环并单独设置每个单元格的

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

我在Windows窗体上有一个datagridview,它绑定到实体框架DbSet:
DbSet.Local.ToBindingList()

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

  myDataGridView.Rows[rowIndex].ReadOnly = false;
它一步一步地完成,而不改变值!(不,我的数据源不是只读的。)

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

  foreach (DataGridViewCell cell in myDataGridView.Rows[rowIndex].Cells)
  {
      cell.ReadOnly = false;
  }
-
获取或设置一个值,该值指示用户是否可以编辑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属性没有更改!为什么???

所以我找到了解决问题的方法,尽管我仍然不确定为什么

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

要重用我的前一个示例,解决方法是循环遍历行并设置每行的只读属性(与设置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);

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

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

这对我来说是非常好的,但是对于我原始问题中的代码为什么不能正确工作的任何见解都将不胜感激

代码隐藏代码何时运行,以及何时将GridView的ReadOnly属性设置为true。你确定它们的顺序正确吗?@Melanie我在设计视图中将GridView的ReadOnly属性设置为true(不是在运行时)。代码是在buttonClick事件上运行的。所以buttonClick事件会导致回发,对吗?如果您在PageLoad()中将GridView的ReadOnly属性设置为true,那么很抱歉,我应该指定我正在使用WinForms。buttonClick事件将向gridview绑定的数据源添加一个新项(基本上是以编程方式添加一行)。我已尝试在FormLoad事件上设置ReadOnly属性,但这似乎也没有什么区别。好的,那么您的数据绑定是在您尝试在单元格上设置属性之前还是之后进行的?这应该被接受为答案。这可能没有实际意义,但我遇到了这个问题,并且单独设置(在我的例子中)列使它们的行为正确。@Aliceraunbaek,很高兴它帮助了您!我将标记为答案,直到/除非有人发布更好的解决方案……如果您想知道原因,可能是由于层次结构和.NET采取了最快的路线。它看到整个视图被设置为ReadOnly=true,并且不使用资源进一步检查对象。这个较高级别的设置会覆盖较低级别的设置。@VenerableAgents在我看来是合理的。。。太糟糕了。NET不能再聪明一点了,但我能理解为什么它会用这种方式来检查以节省时间/资源。。。谢谢你的洞察力!