6

Without explaining the entire context, my problem is basically this:

I have a datagridview on a Windows Form which is bound to an Entity Framework DbSet: dbSet<TEntity>.Local.ToBindingList().

If I set the datagridview's ReadOnly property to true (in design view), and then have this statement in my code:

  myDataGridView.Rows[rowIndex].ReadOnly = false;

It steps right through without changing the value! (And no, my datasource is not readonly.)

Looping through the cells in the row and setting each cell's ReadOnly property individually doesn't work either:

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

.ReadOnly - Gets or sets a value indicating whether the user can edit the cells of the DataGridView control. But it's acting like it can't set for some reason.

Is there a reason that this would happen? I was thinking that maybe the datagridview's ReadOnly property would override any changes made to specific rows/cells (ie. the whole form has to be either readonly or not), but apparently this worked for someone...

There are other ways to accomplish my end-goal, but I would like to know why I can't change this property, as this would be the simplest solution for my situation.


EDIT:

Let me try to clarify my question:

Again, I am aware that there are other ways to accomplish my end-goal, but would like an answer to this issue:

Sorry for the primitive example, but to easily replicate the issue, create a WinForm application, throw a datagridview on it, and past this code into your project:

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

If you put a breakpoint on the last line, and step through it, you will see that the ReadOnly property DOES NOT CHANGE! Why??

sǝɯɐſ
  • 2,470
  • 4
  • 33
  • 47
  • When is your code-behind code running, and when are you setting the GridView's ReadOnly property to true. Are you sure they're happening in the right order? – Melanie Dec 21 '12 at 20:03
  • @Melanie I set the GridView's ReadOnly property to true in the design view (not during runtime). And the code is running on a buttonClick event. – sǝɯɐſ Dec 21 '12 at 20:24
  • So the buttonClick event is causing a postback, right? Perhaps if you set the GridView's ReadOnly property to true in the PageLoad()? – Melanie Dec 21 '12 at 20:26
  • I apologize, I should have specified that I'm working with WinForms. The buttonClick event is adding a new item to the datasource that the gridview is bound to (basically, programmatically adding a row). I have tried setting the ReadOnly property on the FormLoad event, but it doesn't seem to make a difference either. – sǝɯɐſ Dec 21 '12 at 20:37
  • OK, so your databinding is happening before or after you try to set the property on the cell? – Melanie Dec 21 '12 at 20:40
  • @Melanie I should clarify that I meant "I have tried setting the ReadOnly property `of the datagridview to "true"` on the FormLoad event." (then later try to set one row to "false") The databinding is happening on the form creation, long before I attempt to set the ReadOnly property on the row/cells – sǝɯɐſ Dec 21 '12 at 20:50
  • see this link : http://stackoverflow.com/questions/9268763/c-sharp-readonly-datagridview-with-one-enabled-cell – Arash Dec 21 '12 at 21:07
  • Yes, but you said that the buttonClick event is adding a new item to the datasource, so databinding is happening again, right? Or no? – Melanie Dec 21 '12 at 21:20
  • @Arash thanks for the link, looks like someone else ran into the same problem. `.BeginEdit` is going to be my next choice if I can't get an answer here... It would be a viable (but more complicated) solution, but I would **really** like to know why I can't set the `ReadOnly` property. – sǝɯɐſ Dec 21 '12 at 21:46
  • @Melanie I could be mistaken, but as I'm using a `[BindingSource](http://msdn.microsoft.com/en-us/library/xxxf124e.aspx)`, I'm pretty sure databinding does not "happen again" when I add something to the datasource. Anyone correct me if I'm wrong? – sǝɯɐſ Dec 21 '12 at 21:49
  • You may well be right, James. I have no experience with Entity Framework. It's just where I'd look first. Make sure your adding of the data isn't causing your ReadOnly setting on the cell to be overwritten because of the overall ReadOnly setting on the grid. Good luck! – Melanie Dec 21 '12 at 21:55
  • hello @JamesEkema if you don't mind. where did you get this code `dbSet.Local.ToBindingList()`? because actually by default the `DataGridView` column properties is set to false. Can you share your codes in actual format? :) – spajce Dec 22 '12 at 00:44
  • ok, i found out that you're using the Entity Framework by `DbContext` i am right? – spajce Dec 22 '12 at 00:55
  • @spajce Hello, you are correct, I am using EF with `DbContext`... sorry if I didn't make that clear... I don't think EF has anything to do with my problem tho, I was just trying to give a little context... or maybe it does? Also, I'm not quite sure what you mean by `by default the DataGridView column properties is set to false`? – sǝɯɐſ Dec 26 '12 at 16:48
  • sorry for that, i mean the `DataGridView Column` by default `readonly = false`, anyway regarding to your problem, can you share on how did you use this? `dbSet.Local.ToBindingList()` or the entire codes.? – spajce Dec 26 '12 at 17:13
  • @spajce Please see my edit: EF has nothing to do with my issue... (However, to answer your question, `dbSet.Local.ToBindingList()` is bound to a BindingSource, which is then bound to my DataGridView) – sǝɯɐſ Dec 26 '12 at 17:27

1 Answers1

7

So I have found a solution/workaround for my question, althought I am still unsure of the reasons WHY...

Apparently, if you want to change the ReadOnly property of a DataGridView row by row, you cannot set the main DataGridView.ReadOnly property, as evidently this overrides any subsequent changes.

To reuse my previous example, the workaround would be to loop through the rows and set each ROW's ReadOnly property (as opposed to setting the datagridview's ReadOnly property), THEN you can change each row's ReadOnly property individually:

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

This is working great for me, however any insight as to why the code in my original question does not work correctly would be appreciated!

sǝɯɐſ
  • 2,470
  • 4
  • 33
  • 47
  • This should be accepted as an answer. It may not actually make sense, but I had this problem and setting the (in my case) columns individually made them behave correctly. – aliceraunsbaek Aug 27 '15 at 11:58
  • @aliceraunsbaek, glad it helped you! I'll mark as the answer until/unless someone posts a better solution... – sǝɯɐſ Aug 27 '15 at 12:09
  • 1
    If you want to know *WHY*, it's probably due to hierarchy and .NET taking the quickest route. It sees the whole view is set to ReadOnly = true and doesn't use resources checking any further into the object. This higher level overrides lower level settings. – VenerableAgents Sep 28 '15 at 20:14
  • @VenerableAgents sounds reasonable to me... too bad .NET can't be a little smarter with this, but I can understand why it would check that way to save time/resources... Thanks for the insight! – sǝɯɐſ Sep 28 '15 at 21:12