0

I have 1 grid view. On grid-view cell click, it will show relevant data in another gridview.

Now another gridview has DataGridViewComboBoxColumn.

Its data is loading but showing blank on load . It is showing when i click on that DataGridViewComboBoxColumn.

What i want is shows data instead of blank.

This will fill "grdAgingInvoice" gridview other columns

public void grdAgingeInvoice(int RowIndex) {
  DataTable DTCombo = new DataTable();
  try {
    var AgingeInvoice = new DataTable();
    var tEMP = new DataTable();
    string Query;
    grdAgingInvoice.DataSource = null;
    grdAgingInvoice.Columns.Clear();
    Query = "Select Aging, DueInvoiceNo, DueDate,  Balance,CompanyID from AgingInvoice where CompanyID=" + grdCompany.Rows[RowIndex].Cells["CompanyID"].Value.ToString() + " Order by Aging Desc";
    AgingeInvoice = StMethod.GetListDT<DueInvoice>(Query);
    AgingeInvoice.Columns.Add("ContactsName");
    AgingeInvoice.Columns.Add("EmailAddress");
    AgingeInvoice.Columns.Add("Summation");
    AgingeInvoice.Columns.Add("Address");
    AgingeInvoice.Columns.Add("Description");
    var Summation = default(decimal);
    foreach (DataRow dr in AgingeInvoice.Rows) {
      Summation = Summation + Convert.ToDecimal(dr["Balance"]);
      dr["Summation"] = Summation;
      string StrAddress = "SELECT ( Contacts.FirstName+' '+Contacts.LastName) AS Contact, Contacts.EmailAddress,Joblist.Address,JobList.Description FROM         JobList INNER JOIN  Contacts ON JobList.ContactsID = Contacts.ContactsID WHERE  JobList.JobNumber= '" + Program.GetJobNumber(dr["DueInvoiceNo"].ToString()) + "'";
      tEMP = StMethod.GetListDT<InvoiceAddress>(StrAddress);
      if (tEMP.Rows.Count > 0) {
        string s1;
        s1 = tEMP.Rows[0]["Contact"].ToString();
        dr["ContactsName"] = tEMP.Rows[0]["Contact"].ToString();
        dr["EmailAddress"] = tEMP.Rows[0]["EmailAddress"].ToString();
        dr["Address"] = tEMP.Rows[0]["Address"].ToString();
        dr["Description"] = tEMP.Rows[0]["Description"].ToString();
      }
    }
    grdAgingInvoice.DataSource = AgingeInvoice;
    string Query2 = string.Empty;
    String query3 = "SELECT (FirstName +' '+ LastName) AS Contact,";
    Query2 = query3 + "EmailAddress,ContactsID ";
    Query2 = Query2 + "FROM contacts ";
    Query2 = Query2 + "WHERE (IsDelete=0 or IsDelete IS NULL) AND Companyid=";
    Query2 = Query2 + grdCompany.Rows[grdCompany.CurrentRow.Index].Cells["CompanyID"].Value.ToString();
    grdAgingInvoice.Columns.Insert(5, AddContactCombo());
    {
      var withBlock = grdAgingInvoice;
      withBlock.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
      withBlock.Columns["CompanyID"].Visible = true;
      withBlock.Columns["DueInvoiceNo"].HeaderText = "Due InvoiceNo";
      withBlock.Columns["DueDate"].HeaderText = "Due Date";

      // .Columns["ContactsName"].HeaderText = "Contacts Name"   'Add to new column In grid view
      withBlock.Columns["EmailAddress"].HeaderText = "Email Address";   // Add to new column In grid view
      withBlock.Columns["Description"].HeaderText = "Job Description";
      withBlock.Columns["ContactsName"].Visible = true;
    }
  }
  catch (Exception ex) {
    MessageBox.Show(ex.Message.ToString());
  }
}

This will add DataGridViewComboBoxColumn to "grdAgingInvoice" gridview.

public DataGridViewComboBoxColumn AddContactCombo() {
  DataGridViewComboBoxColumn ComboBoxContactsName = new DataGridViewComboBoxColumn();
  try {
    DataTable dt2 = new DataTable();
    dt2 = StMethod.GetListDT<InvoiceAddress>("SELECT (Contacts.FirstName +' '+ Contacts.LastName) as Contact,Contacts.EmailAddress,ContactsID FROM contacts where (Contacts.IsDelete=0 or Contacts.IsDelete IS NULL) AND Contacts.Companyid=" + grdCompany.Rows[grdCompany.CurrentRow.Index].Cells["CompanyID"].Value.ToString());
    ComboBoxContactsName.DataSource = dt2;
    ComboBoxContactsName.DisplayMember = dt2.Columns["Contact"].ToString();
    ComboBoxContactsName.ValueMember = dt2.Columns["ContactsID"].ToString();
    ComboBoxContactsName.DisplayIndex = 5;
    ComboBoxContactsName.HeaderText = "Contacts Name";
    ComboBoxContactsName.DataPropertyName = dt2.Columns["Contact"].ToString();
    ComboBoxContactsName.Name = "cmbContactsName";
    ComboBoxContactsName.DefaultCellStyle.NullValue = dt2.Columns["Contact"];
    return ComboBoxContactsName;
  }
  catch (Exception ex) {
    return ComboBoxContactsName;
  }
}
Harun Diluka Heshan
  • 1,155
  • 2
  • 18
  • 30
Devendra
  • 1
  • 1
  • 3
  • Can you show the code that sets the grids data source and what it looks like? Also, “when/where” is the code adding the combo box column to the grid? Please [edit] your question to make it clear as to what the grid with the combo box column looks like and what the grid’s data source looks like. – JohnG Oct 13 '21 at 20:20
  • @JohnG. edited sir – Devendra Oct 14 '21 at 03:34
  • Well, from what I can tell, in the code that gets the combo box on the line… `ComboBoxContactsName.DataPropertyName = dt2.Columns["Contact"].ToString();` … which should be… `ComboBoxContactsName.DataPropertyName = "Contact";` … is mating the combo box column to a column in the grids data source i.e. the column named “Contact.” However, when you look at the code that gets the grids table, I do not see a “Contact” field in the grids table. However… I do see a “ContactsName” field. – JohnG Oct 14 '21 at 05:01
  • Looking at the first code snippet, from the query we can see the columns… `Aging, DueInvoiceNo, DueDate, Balance, CompanyID` … then some additional columns are manually added yet none have the name ”Contact.” Granted, you can see below where the address is “selected” and it creates a “Contact” column, unfortunately, this value is taken and put into the “ContactsName” field of the original table… `dr["ContactsName"] = tEMP.Rows[0]["Contact"].ToString();` … This looks odd and I am betting you need to set the `DataPropertyName` to “ContactsName.” Sorry if I missing something? – JohnG Oct 14 '21 at 05:02
  • I have set following but same problem. ComboBoxContactsName.DisplayMember = dt2.Columns["Contact"].ToString(); ComboBoxContactsName.ValueMember = dt2.Columns["ContactsID"].ToString(); cmbContactsName.DataPropertyName = "ContactsName"; – Devendra Oct 14 '21 at 05:59
  • Are you sure you are not getting any errors? Assuming you get no errors, then, is the column “ADDED” to the existing columns in the grid and NOT mated to the “ContactsName” column? If the column is simply added to the existing columns then obviously the `DataPropertyName` is not matching one of the columns in the grid table. Also, it appears the code is setting the grids `DataSource` FIRST, then the combo box column is added. I suggest you add the combo box column to the grid BEFORE you set the grids data source. – JohnG Oct 14 '21 at 06:22
  • Also, I highly recommend that BEFORE you set the grids data source you make a method that takes the grids data source and checks the combo box columns values to see that ALL the items in the grids `DataSource` are also contained in the combo boxes data source. If one (1) or more items are in the grids data source and are NOT in the combo boxes data source, then you will get the grids `DataError` when you attempt to set the grids data source. – JohnG Oct 14 '21 at 06:23
  • grdAgingInvoice_DataError event i am getting something like this Exception = {"DataGridViewComboBoxCell value is not valid."} – Devendra Oct 14 '21 at 07:03
  • That means that one or more of the rows in the “AgingeInvoice“ table in the column “ContactsName” is NOT in the combo box columns `DataSource`. Check my last comment. Create a method that loops through the “AgingeInvoice“ table rows and check each “ContactsName” value. Check to see if the value is in the combo box columns data source, if the value is found then great, however if the value is NOT found in the combo box columns data source, then that will throw a data error. Therefore the easiest solution (not the best) is to simply add the value to the combo box columns data source. – JohnG Oct 14 '21 at 07:39
  • i have just checked. there are almost 8-10 rows where there are “ContactsName” is not in the combo box columns . Now implementing a method as per your suggestion. hope it will solve my issue – Devendra Oct 14 '21 at 12:17
  • but that "DataGridViewComboBoxCell value is not valid." error is still there – Devendra Oct 14 '21 at 12:51
  • Please be patient. I am aware that working with combo boxes in a `DataGridView` can be frustrating at times especially if you have never used them before. Often times, it will “appear” the items are the same when they are not. So, can you post the code that checks the grids data source and adds the items to the combo box items collection if they are not found in the combo boxes items collection. – JohnG Oct 14 '21 at 17:23
  • Also, as a stab in the dark… what happens if you comment out the line of code… `ComboBoxContactsName.ValueMember = dt2.Columns["ContactsID"].ToString();` … in the `AddContactCombo` method and run it? Do you still get the `DataError`? – JohnG Oct 14 '21 at 17:28
  • stab is working. commented following line cmbContactsName.ValueMember = DTCombo.Columns["CID"].ToString(); and now Datagridviewcomboboxcolumn showing data on load and DataError is not throwing for each and every row. They are coming for just 1-2 rows – Devendra Oct 15 '21 at 03:41
  • Unfortunately, One (1) `DataError` is no different than a hundred (100)… you still have to fix it. You cannot ignore the grids `DataError`… ever. Some are tempted to simply wire-up the grids `DataError` event and swallow/ignore the error. If the error is ignored, then It is not uncommon to see a “sluggish” UI or worse specifically to the data errors with the combo boxes is almost guaranteed to be show stopping freeze. My point being… never ignore the grids `DataError` even if it gets thrown sporadically. – JohnG Oct 15 '21 at 04:43
  • if you want to show the code that checks the grids data source with the combo boxes data source, then I can give it glance. You state that you still get the data error but only with a couple of cells? If this is the case, then I would look at the new method that checks the values for the combo box. Your call. – JohnG Oct 15 '21 at 04:44
  • Now no rows is showing DataError. so all rows are free of DataError. but I want to use value member for forther action and I have already commented so how can i achive same thing cmbContactsName.ValueMember = DTCombo.Columns["CID"].ToString(); – Devendra Oct 15 '21 at 07:32
  • I mean no disrespect and I may be missing something; however, I am not sure what you want to do here makes a lot of sense. If the grids columns are… `Aging`, `DueInvoiceNo`, `DueDate`, `Balance,CompanyID` (added) `ContactsName`, `EmailAddress`, `Sumation`, `Address` and `Description`. And you have a combo box with the `ContactsName`… AND IF the user changed a combo box value on a row, then wouldn’t you have to change the “Email, Summation, Address and Description” fields on that row? I am really not understanding this. Can you clarify? – JohnG Oct 16 '21 at 06:54
  • @JohnG. yes. if user change "Contact Name" DatagridcomboboxColumn then according to it, its relevant email address will be changed in gridview – Devendra Oct 16 '21 at 09:43
  • If you have the code to change the other fields in the grid then great. As far as the combo boxes `ValueMember`, you can set it to the `ContactID`, however, you will need to add a `ContactID` type column to the grid in addition to setting the combo boxes `DataPropertyName` to point to that column. – JohnG Oct 16 '21 at 18:02
  • yeps. now everything is working perfectly. I have added "ContactID" filed in select query which will fetch data for "grdAgingInvoice" gridview. So "ContactID" field is added in gridview and then set the following cmbContactsName.DisplayMember = DTCombo.Columns["Contact3"].ToString(); cmbContactsName.ValueMember = DTCombo.Columns["ContactsID"].ToString(); cmbContactsName.DataPropertyName = "ContactsID"; – Devendra Oct 17 '21 at 07:18
  • also now there is no DataError in any of the gridview columns – Devendra Oct 17 '21 at 07:20
  • I am glad you got it working. I have to ask, … the code… `cmbContactsName.ValueMember = DTCombo.Columns["ContactsID"].ToString();` … is very odd … specifically … `DTCombo.Columns["ContactsID"].ToString();` … the code is “referencing” the column by “NAME”! There is no need to get the columns “name” when “referencing” the column by its “name.” “ContactID” accomplishes the same thing. But if it works for you, go for it. – JohnG Oct 17 '21 at 08:40

1 Answers1

0

You can use NullValue property of DataGridViewComboBoxColumn.DefaultCellStyle to set a default ComboBox value:

int columnIndex = Your ComboBoxColumn index;
(dataGridView1.Columns[columnIndex] as DataGridViewComboBoxColumn).DefaultCellStyle.NullValue = "Nothing selected";

enter image description here

Auditive
  • 1,607
  • 1
  • 7
  • 13
  • My requirement is it should display on load and data is coming perfectly but they are showing when i click on DataGridViewComboBoxColumn. I am new otherwise i will explain it by showing images. – Devendra Oct 13 '21 at 12:49
  • And I said how you can set a default value to see it in Cell before you click on it. – Auditive Oct 13 '21 at 13:04
  • yes. but it is showing blank even if value is not null. This is my question with picture for better idea. https://www.codeproject.com/Questions/5314492/Datagridviewcomboboxcolumn-showing-blank – Devendra Oct 13 '21 at 15:01