1

I have a DataGridView in my applicaiton, but I want to limit it to 20 rows only, however because it is data-bound, I get the InvalidOperationException. Through research I have come across virtual mode, but this looks incredibly confusing for a starter like me. Furthermore, I have seen people say setting the DGV.DataSource = null; to solve the problem, but this doesn't work for me.

I basically, click a button, and then the DataGridView populates with information. The only work around I have in place, is limiting the user to enter only 20 instances of my object. Then they have to delete one in order to enter another.

Is there any way I can set a maximum row limit with a data-bound DataGridView?

EDIT

In my separate class file (objectStorage.cs) I have this

public class objectStorage: IComparable<objectStorage>
{
    public string objID { get; set; }
    public string objName { get; set; }
    public string objDescription { get; set; }


    public static List<objectStorage> objArray = new List<objectStorage>();
}

Then in my form where I add a new object (addObj.cs) I have this:

private void objCreationBtn_Click(object sender, EventArgs e)
    {
         objectStorage.objArray.Add(new objectStorage
         {
            objID = objIDValueTxt.Text,
            objName = objNameRTB.Text,
            objDescription = objDescRTB.Text,
         });

    }

Then In my main form I have the DGV (Where I assigned the data source to objectStorage in the GUI, and thus created a binding source) which I have created a method to show the objects, like this in a button press:

private void displayObjBtn_Click(object sender, EventArgs e)
{
        showObjects();
}

private void showObjects()
    {

       objectStorageBindingSource.DataSource = null;

       objectStorageBindingSource.DataSource = objectStorage.objArray; 
    }

This works completely okay, but obviously includes no limit to the row count, and I cannot do this because of the data-bound problem.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
KieranLowe
  • 81
  • 1
  • 10
  • Why not just enforce the limit in the binding source? You can separate a backing list of entities from the list bound to the grid, the bound list could even be made from LINQ: `myEntities.Take(20).ToList()`, all this can be handled in the view model. – Adam Houldsworth Apr 16 '15 at 10:21
  • @AdamHouldsworth How would I go about doing that? I have used the GUI to bind the data source of my DGV to my object, is this what you mean by view model? I'm apologise if I'm asking stupid questions, but I'm just trying to broaden my knowledge of C# and really appreciate your help! – KieranLowe Apr 16 '15 at 10:29
  • @IAmZingy Without seeing how you have approached the problem I can't really provide an explanation. There should be some code you've written (unless this is all designer-lead) that assigns a list to the DGV's data source property. This list can be changed to enforce the limit. – Adam Houldsworth Apr 16 '15 at 10:32
  • @AdamHouldsworth I have a class named objectStorage.cs, and using the Form Designer, I assigned the Data Source of my DGV to that class, this then created a BindingList automatically named, objectStorageBindingList in the Form Designer, is this what you meant? – KieranLowe Apr 16 '15 at 10:39
  • @IAmZingy Yeah. In the code-behind you'll see that this list gets assign to the data source property. What you can instead do is take control in the form's code-behind and assign the property manually. Take your `objectStorage` query it for 20 items, make a list of those 20, and apply that list as the data source. – Adam Houldsworth Apr 16 '15 at 10:41
  • @AdamHouldsworth Okay thankyou, how could I go about doing that? I'm sorry, you probably think I'm an idiot. Do you mean, find the code behind where this binding list is, then query it (What do you mean by this? Like LINQ?) Then set the binding list to those 20 items and give that new list the DGV.DataSource property? – KieranLowe Apr 16 '15 at 10:56
  • @IAmZingy Yeah exactly as you describe. I'll post an answer for you. – Adam Houldsworth Apr 16 '15 at 11:32
  • I've provided an answer which might be easier to consume that full-blown virtual mode operation, but in essence the linked question tackles the issue of performance of large datasets. This question is missing some more surrounding information that would allow it to be valuable on its own, but I don't want that to hinder helping you find a solution. – Adam Houldsworth Apr 16 '15 at 11:47

1 Answers1

0

Caveat

In the long run, this is not the approach you should take, but I provide this as a pragmatic answer given that the question is quite specific to your approach and lacking in some surrounding details (which will eventually mean the question will be closed).

It also makes the assumption that "virtual mode" operation is not what you are after (as per the linked duplicate question, which provides an answer).

Please preface the remainder of the answer with the above in mind.


Limiting rows at the source

Further to our discussion in the comments, and without seeing what the code currently looks like, I would suggest something straightforward.

The DataGridView will be on a Form, which will have a code-behind file. In this file, we want to make the amendments necessary to limit the list to 20 items:

using System.Linq;
using System.Collections.Generic;

public class MyForm : Form
{
    // Event handler for the Forms Load event
    public void MyForm_OnLoad(object sender, EventArgs e)
    {
        // Take 20 items from whatever source you are currently using in the DGV.
        List<MyDataBoundItem> items = objectStorage.Items.Take(20).ToList();

        dataGridView1.DataSource = items;
    }
}

A binding list isn't always required, a List<T> can be used but it will be readonly I think, whereas a BindingList<T> supports adding and removing rows.

Also remember to remove the designer-lead solution, as they will interfere with each other.

The DataGridView control, if memory serves, does not provide a mechanism for enforcing maximum rows. You will have to handle cases where the user is trying to add a new row and is at the maximum, assuming the grid allows for adding rows. Other user input scenarios may need manual intervention.


A brief note on patterns

As to the brief mention of a "view model", disregard this for now. It is a term borrowed from one of a few standard UI patterns for separating handling of a UI into testable chunks. It is a more advanced topic that you should read up on when you've gone through a little of the pain of non-patterned UI coding :-)

For future delectation, search for "MVC", "MVP", and "MVVM".

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • Thank you for all this information, it it makes it any easier, I have now included code which I completely forgot to do when asking the question. So I'm incredibly sorry! I have edited my original question with the code I am using, does this help? – KieranLowe Apr 16 '15 at 12:08
  • @IAmZingy I've reopened the question, in case anyone else has something further to add. – Adam Houldsworth Apr 16 '15 at 12:36