Tech Off Thread

17 posts

C# Error - Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound.

Back to Forum: Tech Off
  • User profile image
    tomtomh5

    C# 2010 express edition. I have created a dataset with a datagridview and 2 forms. One form displaying the datagridview and another that the user types the data into via text boxes to be saved into the dataset. 

    I am attempting to insert data to a data table(on customerForm) via another form(addcustForm). When I debug and open addcustForm, then enter data to the textboxes on addcustForm, then click save, I get the error "Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound." The error highlights the code on line 33 in the customerForm form.

    Here is the code for customerForm:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Lewis_Warby_Airbrushing
    {
    public partial class customerForm : Form
    {
    public customerForm()
    {
    InitializeComponent();
    }
    
    private void customerForm_Load(object sender, EventArgs e)
    {
    customerTBLDataGridView.DataSource = customersDataSet;
    }
    
    
    //opens the add customer window
    addcustForm addcustForm = new addcustForm();
    private void addcustBTN_Click(object sender, EventArgs e)
    {
    if (addcustForm == null || addcustForm.IsDisposed == true)
    addcustForm = new addcustForm();
    addcustForm.ShowDialog();
    
    customerTBLDataGridView.Rows.Add(addcustForm.strFirst, addcustForm.strSurename, addcustForm.strAddress1, addcustForm.strAddress2, addcustForm.strCounty, addcustForm.strPost, addcustForm.strContact, addcustForm.strEmail);
    customerTBLDataGridView.DataSource = customersDataSet;
    
    }
    
    }
    }

    And here's the code for addcustForm:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Lewis_Warby_Airbrushing
    {
    public partial class addcustForm : Form
    {
    public addcustForm()
    {
    InitializeComponent();
    
    }
    
    
    
    public String strFirst = "";
    public String strSurename = "";
    public String strAddress1 = "";
    public String strAddress2 = "";
    public String strCounty = "";
    public String strPost = "";
    public String strContact = "";
    public String strEmail = "";
    
    
    //code for the save button
    private void saveBTN_Click(object sender, EventArgs e)
    {
    {
    if (String.IsNullOrEmpty(txtFirst.Text))
    {
    MessageBox.Show("Please input First Name");
    }
    
    if (String.IsNullOrEmpty(txtSurename.Text))
    {
    MessageBox.Show("Please input Surename ");
    }
    
    if (String.IsNullOrEmpty(txtAddress1.Text))
    {
    MessageBox.Show("Please input Adddress Line 1");
    
    }
    if (String.IsNullOrEmpty(txtAddress2.Text))
    {
    MessageBox.Show("Please input Address Line 2");
    }
    if (String.IsNullOrEmpty(txtContact.Text))
    {
    MessageBox.Show("Please input a Contact Number");
    }
    if (String.IsNullOrEmpty(txtCounty.Text))
    {
    MessageBox.Show("Please input County");
    }
    
    if (String.IsNullOrEmpty(txtEmail.Text))
    {
    MessageBox.Show("Please input an Email Address");
    }
    }
    if (String.IsNullOrEmpty(txtPost.Text))
    {
    MessageBox.Show("Please input Post COde");
    }
    
    strFirst = txtFirst.Text;
    strSurename = txtSurename.Text;
    strAddress1 = txtAddress1.Text;
    strAddress2 = txtAddress2.Text;
    strPost = txtPost.Text;
    strCounty = txtCounty.Text;
    strEmail = txtEmail.Text;
    strContact = txtContact.Text;
    this.Close();
    }
    
    //code for the cancel button
    private void cancelBTN_Click(object sender, EventArgs e)
    {
    this.Close();
    }
    
    }
    }

    ErrorMessage

  • User profile image
    GreyLensman

    why are you adding rows to the grid?  When bound to a data source you should add row to the data source and then rebind your data.   The error you encountered is accurate. Instead of manipulating the grid, manipulate the data.

  • User profile image
    tomtomh5

    I'm not arguing that it isn't accurate, I'm asking how to avoid it?

  • User profile image
    GreyLensman

    instead of grid.rows.add(), add a row to the data source the grid is bound to. That will have the same effect without causing the error.  I.e., if the grid is bound to a data table, add a row withe the new data To the data table then do a rebind to the grid. 

     

    The error is accurate. You can't add row directly to a bound grid. You must add the row instead to the data source which will in turn make the related changes to the displayed grid..

  • User profile image
    AndyC

    As GreyLensman says, the point of databinding is that the control always reflects what is in it's source object and so should not be manipulated directly itself. And if you're binding to an object that provides appropriate notifications, it isn't necessary to rebind, simply make your changes to the underlying data object and the changes are reflected in the grid automatically.

  • User profile image
    tomtomh5

    How do i do that?

  • User profile image
    GreyLensman

    Well, first of all, read the documentation.  You are completely glossing over dozens of the finer points of data binding. 

    As to how to do that?  We are not here to "write" your code for you.  Your pseudo code above does not provide enough data to be able to be of concrete help.  You appear to have a dataset entitled "customersDataSet".  You have not defined what this represents.  A dataset is normally a collection of one or more DataTable objects.  A DataTable object is a collection of DataRows.  A DataRow is a collection of DataColumns.  Using one of the dozens of routes open to you you could do something like the following:

     

    DataSet ds = customersDataSet;
    DataTable tbl = ds.Tables["sometablename"]; // reference to table containing data we are "adding" data too
    
    tbl.Rows.Add(new Object[] { 
    "column 1 content",
    "column 2 content",
    "column 3 content",
    "etc..."
    });
    tbl.AcceptChanges(); // "accept" changes in bound table

  • User profile image
    tomtomh5

    @GreyLensman:

    I'm trying to create an application where the user can access customer details, and add, edit remove and save them. In the addcustForm, when the user types the data into the texts boxes and clicks the save button, I want the data they have just entered, to be added to the datatable which is being displayed in the customerForm. And they can then shut down the application (i.e to log off, reboot etc.) and then launch the application again, with the data still saved.

    I'm not asking you to write code for me, I'm asking for advice of how I should write it. And if there's any key points I have to follow, and tips or tricks that may come in handy. But thank you for your help so far. Do you know of any video tutorials that could help me?

  • User profile image
    GreyLensman

    Well your project has several holes to which you could drive a truck through.

    I gather that you want to present a form to the user which will have the ability to display existing data.  Ideally you also want to allow for editing existing data and possibly inserting new records.  This implies that you wish to read existing records from somewhere, allow for insert/update/delete operations, and update that same "somewhere".

    How you do this is highly dependent upon what "somewhere" is.  For example is it an access database (yuck), is it a SQL database from the provider of your choice (Oracle, IBM, Microsoft, MySQL, etc.)

    Microsoft has an abstraction layer known as the "DataSet" which you can add to your program.  Using that "object" you can add tables along with queries to it.  You can use these objects to bind to your grid.

    In your example you used "customersDataSet".  I did not see that you set the "datamember" property.  In the case of the DataSet this would represent the datatable object defined on the dataset designer object.  If you go this route you can use a certain amount of automatic data operations if desired.  Of course you can also go 100% manual if you really want a challenge.

     

     

     

  • User profile image
    tomtomh5

    @GreyLensman:

    Yes that correct, I want the data to be displayed in one form (customerForm), and when clicking a button a second form opens (addcustForm) to allow the user to enter data to text boxes with labels next to them ( corresponding to what they are entering (name, address etc)). 

    I have a local database (created by clicking new > add new > local database (.mdf)) and then adding a table to it. Then creating a Datasource and database diagram and making a datagridview on the customerForm.

    When the use hits the save button on the addcustForm i want the new data to be displayed in the datagridview on the customerForm, and obviously saved in the local database.

  • User profile image
    AndyC

    Create a row for the bound datatable, fill out the fields and then add it to the datatable. Databinding will then take care of updating the grid for you.

  • User profile image
    tomtomh5

    Thanks Andy! But how do i do that?

  • User profile image
    GreyLensman

    Have you even looked at MSDN's documentation?  You appear to be using a DataGridView control.   This implies that you are using a Windows Forms based application.  

    Are you aware that data entry directly in the grid is possible?  I.E., you could eliminate the need to have a separate data entry form entirely.  This requires that you have a strongly typed data source. If you opt for this you simply let the grid add the row for you.  I.E, if you enable inserts on the grid control it will automatically (when databound) add the row.  

    If you want to get exotic you can attach events to the grid to capture and validate edits.  For example if you want to verify that the 3rd column contains numeric values between 12-50, that is possible although tricky.

    The DataGridView control fully supports edits, inserts and deletes.  This is not natively enabled however with a datasource that supports updates/insert/delete, and the enabling of these on the datagridview control the grid pretty much does it all for you.

     

    note:  as you have yet to identify precisely how you are reading/writing your data we cannot provide you with the "how do I do that answer".  I am guessing you are using  a ODBC datasource although that is a pure guess and likely wrong.

     

    I remind you that Microsoft has online documentation.  Yes the MSDN website has pitiful search capabilities (and Bing is clueless), but Google does  a respectable job.

  • User profile image
    tomtomh5

    C# 2010 express edition.

    I know I can enter data to the grid directly, but that doesn't look very "professional". I want it to be "user-friendly" so an additional form where the user enters the data is needed. I've explained how i create the dataset in a previous answer. 

    I haven't read the documentation, but I will shortly.

  • User profile image
    qwerty1379

    Make the DataSet of your grid either a DataTable (if you want to show the whole underlying table), or a BindingList<T> (if you want to run a query to get a subset of the underlying table to populate the gird).

    When the user adds a new record, simply add it to the DataTable or BindingList, and the grid should update.

    Don't look to MSDN to learn about parts of .NET you're not familar with; that's a path to sure frustration.  Look for questions or tutorials in CodeProject, StackOverflow, or similar resources; that should help you get on track.  

  • User profile image
    xiaoyuandlg

    Troublesome problems

  • User profile image
    tomtomh5

    Hi guys,

    Thanks for all the replies, for some reason I wasn't getting email notifications. But anyway, I've since watched a tutorial on YouTube and figured it out. Its not the most "secure" way of doing it (e.g sql attacks etc) but it works.

    I'll take your advice on board and hopefully make something useful and good out of it :)

    thanks

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.