質問

I have a datagridview which I'm using for data entry. I've done this before with all text columns, and it worked great. But now I want one of the columns to be a databound combobox so the user can select options. When I do this, the resulting gridview's datasource ends up with empty rows (but the right quantity). What am I missing?

Here is code:

 DataGridViewComboBoxColumn cboCategory = new DataGridViewComboBoxColumn();
 {
     cboCategory.HeaderText = "Category";
     cboCategory.DataSource = downtimeCategories;
     cboCategory.DisplayMember = "Name";
     cboCategory.ValueMember = "CategoryID";
     cboCategory.DataPropertyName = "CategoryID";

     gridDowntime.Columns.Add(cboCategory);
 }

Then code to grab gridview's datasource:

DataTable dt = (gridDowntime.DataSource as DataTable);

Everytime I get a table with the correct number of rows, but all the rows are empty (although they are long rows, the dataset visualizer has to scroll to show the entire cell). How can I find the error and correct?

EDIT: Is there some specific additional information I should provide here?

役に立ちましたか?

解決

Here is a simple example project that I just cooked up.

The key thing I think you are getting wrong is that the DataPropertyName property of the DataGridViewComboboxColumn needs to refer to the datasource of the DataGridView, not the column.

public Form1()
{
    InitializeComponent();

    DataTable dt = new DataTable("Customers");
    DataColumn dc;

    dc = new DataColumn();
    dc.DataType = typeof(int);
    dc.ColumnName = "CustomerID";

    dt.Columns.Add(dc);
    dt.Columns.Add(new DataColumn("LastName"));
    dt.Columns.Add(new DataColumn("FirstName"));
    // Concatenation of first and last names 
    dt.Columns.Add(new DataColumn("FullName"));
    dt.Columns.Add(new DataColumn("Address"));
    dt.Columns.Add(new DataColumn("City"));
    dt.Columns.Add(new DataColumn("State"));
    dt.Columns.Add(new DataColumn("Zip"));
    dt.Columns.Add(new DataColumn("Phone"));

    dc = new DataColumn();
    dc.DataType = typeof(DateTime);
    dc.ColumnName = "LastPurchaseDate";
    dt.Columns.Add(dc);

    dc = new DataColumn();
    dc.DataType = typeof(int);
    dc.ColumnName = "CustomerType";
    dt.Columns.Add(dc);

    // Populate the table 
    dt.Rows.Add(2, "Baggins", "Bilbo", "Baggins, Bilbo", "Bagshot Row #1", "Hobbiton", "SH", "00001", "555-2222", DateTime.Parse("24/9/2008"), 1);
    dt.Rows.Add(1, "Baggins", "Frodo", "Baggins, Frodo", "Bagshot Row #2", "Hobbiton", "SH", "00001", "555-1111", DateTime.Parse("14/9/2008"), 1);
    dt.Rows.Add(6, "Bolger", "Fatty", "Bolger, Fatty", "ProudFeet Creek", "Hobbiton", "SH", "00001", "555-1111", DateTime.Parse("14/9/2008"), 1); 
    dt.Rows.Add(4, "Elessar", "Aragorn", "Elessar, Aragorn", "Citadel", "Minas Tirith", "Gondor", "00000", "555-0000", DateTime.Parse("14/9/2008"), 4);
    dt.Rows.Add(5, "Evenstar", "Arwin", "Evenstar, Arwin", "Citadel", "Minas Tirith", "Gondor", "00000", "555-0001", DateTime.Parse("23/9/2008"), 4);
    dt.Rows.Add(3, "Greyhame", "Gandalf", "Grayhame, Gandalf", DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, 3);

    DataGridViewComboBoxColumn cboCategory = new DataGridViewComboBoxColumn();

    List<CustomerType> customerTypes = new List<CustomerType> { new CustomerType { Id = 1, Name = "Good" }, new CustomerType { Id = 4, Name = "Bad" }, new CustomerType { Id = 3, Name = "Ugly" } };

    cboCategory.HeaderText = "Customer Type";
    cboCategory.DataSource = customerTypes;
    cboCategory.DisplayMember = "Name";
    cboCategory.ValueMember = "Id";
    cboCategory.DataPropertyName = "CustomerType";

    dataGridView1.Columns.Add(cboCategory);

    dataGridView1.DataSource = dt;

}

Bit of fluff in there - grabbed that datatable code right off the interwebs. But the key part here is the setting of properties for the combobox column.

My datasource is a list of customertype objects:

public class CustomerType
{
    public int Id { get; set; }
    public string Name { get; set; }
}

So I need to set DisplayMember on the column to "Name" and ValueMember to "Id" since this references the columns datasource. However for the DataPropertyName was set the value to "CustomerType" which is the name of a column in the DataTable that we have bound to the DataGridView.


So after a wee bit of discussion in chat it turns out that the above is true but that you also need to ensure that the types of your id columns match.

The datatable used to provide data to the combobox column was generated from a sql query and had the id column of type in. Your backing datatable had the id column made like so:

dt.Columns.Add(new DataColumn("Category")); 

This defaults to a column of type string. Try instead something like:

downtimeEntries.Columns.Add("Category", typeof(int));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top