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]
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;
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;
}
}
精彩评论