Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataGridViewComboBoxColumn DataSource?

I'm trying to get something set up in a DataGridView. It seems like this should be pretty straightforward but I'm having trouble. I want to display three columns:

  • CodeID
  • CodeName
  • ComboBox with DisplayMember of TypeName, ValueMember of TypeID

I want to be able to select from all possible values of TypeName. Here's my dilemma:

If I load all of this into one DataTable and set the DataGridView as the DataSource, I can display the existing TypeName for that record, but the combo box will not include any other values. If I set the DataSource for the DataGridViewComboBoxColumn to a separate DataTable that includes all possible TypeNames, the existing value is not displayed.

DataGridView is really annoying to work with so either a solution for this or a viable alternative would be appreciated.

Edit: it appears the issue is caused by my wanting to have a separate item for DisplayMember and ValueMember. The following works, if I don't worry about setting the ID as the ValueMember:

var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "Type",
    DataPropertyName = "Type"
}

If I do the following, the right types are selected, but I can't change the selection in the combo box:

var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "TypeID",
    DataPropertyName = "TypeID"
}

If I use the following I get a FormatException error as it's trying to populate:

var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "TypeID",
    DataPropertyName = "Type"
}

edit: typeList is a simple DataTable populated by the following:

SELECT DISTINCT IT.InsuranceTypeID, IT.[Type]
FROM InsuranceType IT
WHERE IT.ClientID = @ClientID
ORDER BY [Type]
like image 431
John Straka Avatar asked Oct 05 '11 19:10

John Straka


2 Answers

I had a similar (I think) issue, and the solution for me was to set the DataSource for the DataGridViewComboBoxColumn before setting the DataSource for the DataGridView.

In my case, my DataSources are a List<T> and a BindingList<T> respectively but it should work the same with DataTables:

DataGridViewComboBoxColumn categoryColumn = (DataGridViewComboBoxColumn)_ItemsGrid.Columns["CategoryID"];
categoryColumn.DataSource = categories;

_ItemsGrid.DataSource = items;
like image 161
C-Pound Guru Avatar answered Oct 15 '22 05:10

C-Pound Guru


Ok, I came up with an example ClientInfo and InsuranceDetails that I think might mimic what you are trying to do. Let me know if these details arent quite right. This example will populate the DataGridViewComboBox and set the value based on the InsuranceDetails (specifically at: InsurDetailz = all_insurance_types[2])

   public partial class Form1 : Form
   {
      private ClientInfo _myClient;
      private BindingList<InsuranceDetails> all_insurance_types =
         new BindingList<InsuranceDetails>();

      public Form1()
      {
         InitializeComponent();

         DataGridView grid = new DataGridView();
         grid.Dock = DockStyle.Fill;
         grid.AutoGenerateColumns = true;

         all_insurance_types.Add(new InsuranceDetails(1, "Health"));
         all_insurance_types.Add(new InsuranceDetails(2, "Home"));
         all_insurance_types.Add(new InsuranceDetails(3, "Life"));

         var col = new DataGridViewComboBoxColumn
         {
            DataSource = all_insurance_types,
            HeaderText = "Insurance Type",
            DataPropertyName = "InsurDetailz",
            DisplayMember = "ItType",
            ValueMember = "Self",
         };

         _myClient = new ClientInfo { 
            InsurDetailz = all_insurance_types[2], Name = "Jimbo" };
         grid.Columns.Add(col);
         grid.DataSource = new BindingList<ClientInfo> { _myClient };
         this.Controls.Add(grid);

         this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
      }

      void Form1_FormClosing(object sender, FormClosingEventArgs e)
      {
         // make sure its updated
         InsuranceDetails c = _myClient.InsurDetailz;
         string name = _myClient.Name;
         // Place breakpoint here to see the changes in _myClient 
         throw new NotImplementedException();
      }
   }

   class ClientInfo
   {
      public string Name { get; set; }
      public InsuranceDetails InsurDetailz { get; set; }
   }

   class InsuranceDetails
   {
      public int InsuranceTypeID { get; set; }
      public String ItType { get; set; }
      public InsuranceDetails Self { get { return this; } }

      public InsuranceDetails(int typeId, String itType)
      {
         this.InsuranceTypeID = typeId;
         this.ItType = itType;
      }
   }
like image 7
SwDevMan81 Avatar answered Oct 15 '22 05:10

SwDevMan81