Adding bound combobox to datagridview
The scenario is almost the same as http://arsalantamiz.blogspot.com/2008/09/binding-datagridview-combobox-column.html. but I can't get it working on c#...
I have mySql db with two tables: 1. protocols 2. pcapdata
In protocols tables I have a two fields: idprotocols and protocolName
Int the pcaps table I have wizardProtocol (which is "linked" to the idprotocols field)
What I'm trying to get is to have a combobox containing names which will replace the wizardprotocol field. Next, If the user updates the "names" combobox the wizardProtocol will be changed accordingly (so I will be able to update the changes in the database accordingly).
Now, after reading some information on the net: I've written the following code:
public void Bind(ref DataGridView dataGridView)
{
try
{
mySqlDataAdapter = new MySqlDataAdapter(SELECT_ALL_PCAP, _con);
mySqlCommandBuilder = new MySqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.UpdateCommand = mySqlCommandBuilder.GetUpdateCommand();
mySqlDataAdapter.DeleteCommand = mySqlCommandBuilder.GetDeleteCommand();
mySqlDataAdapter.InsertCommand = mySqlCommandBuilder.GetInsertCommand();
dataSet = new DataSet();
mySqlDataAdapter.Fill(dataSet, "pcap");
MySqlDataAdapter adp2 = new MySqlDataAdapter(SELECT_ALL_PROTOCOL, _con);
MySqlCommandBuilder builder = new MySqlCommandBuilder(adp2);
adp2.UpdateCommand = builder.GetUpdateCommand();
adp2.DeleteCommand = builder.GetDeleteCommand();
adp2.InsertCommand = builder.GetInsertCommand();
adp2.Fill(dataSet, "protocol");
bindingSource = new BindingSource();
bindingSource.DataSource = dataSet;
bindingSource.DataMember = "pcap";
dataGridView.DataSource = bindingSource;
dataGridView.Columns["length"].ReadOnly = true;
dataGridView.Columns["length"].DefaultCellStyle.ForeColor = System.Drawing.Color.SandyBrown;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
DataGridViewComboBoxColumn colType = new DataGridViewComboBoxColumn();
colType.HeaderText = "Type";
colType.DropDownWidth = 90;
colType.Width = 90;
colType.DataPropertyName = "wizardProtocol";
colType.DataSource = bindingSource;
colType.DisplayMember = "protocolName";
colType.ValueMember = "idprotocols";
dataGridView.Columns.Insert(dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1, colType);
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString());
}
}
I'm trying to manipulable the DisplayMember property, but I fail (I know that the problem is with probably with my data-binding, but I can't figure it out...)
UPDATE: Thanks to the answer, I'm re-attaching the fixed code
mySqlDataAdapter = new MySqlDataAdapter(SELECT_ALL_PCAP, _con);
mySqlCommandBuilder = new MySqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.UpdateCommand = mySqlCommandBuilder.GetUpdateCommand();
mySqlDataAdapter.DeleteCommand = mySqlCommandBuilder.GetDeleteCommand();
mySqlDataAdapter.InsertCommand = mySqlCommandBuilder.GetInsertCommand();
dataSet = new DataSet();
mySqlDataAdapter.Fill(dataSet, "pcap");
MySqlDataAdapter adp2 = new MySqlDataAdapter(SELECT_ALL_PROTOCOL, _con);
MySqlCommandBuilder builder = new MySqlCommandBuilder(adp2);
adp2.UpdateCommand = builder.GetUpdateCommand();
adp2.DeleteCommand = builder.GetDeleteCommand();
adp2.InsertCommand = builder.GetInsertCommand();
adp2.Fill(dataSet, "protocol");
bindingSource = new BindingSource();
bindingSource.DataSource = dataSet;
bindingSource.DataMember = "pcap";
dataGridView.DataSource = bindingSource;
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
DataGridViewComboBoxColumn colType = new DataGridViewComboBoxColumn();
BindingSource wizardBindingSource = new BindingSource();
wizardBindingSource.DataSource = dataSet;
wizardBindingSource.DataMember = "protocol";
colType.HeaderText = "Type";
colType.DropDownWidth = 90;
colType.Width = 90;
colType.DataPropertyName = "wizardProtocol";
colType.DataSource = wizardBindingSource;
colType.DisplayMember = "protocolName";
colTy开发者_开发技巧pe.ValueMember = "idprotocols";
dataGridView.Columns.Insert(dataGridView.Columns.GetColumnCount(DataGridViewElementStates.None) - 1, colType);
The most obvious thing that you are doing wrong is that you use the same binding source for both your datagridview and for your comboboxcolumn. If you look at the example you provided you'll notice that they create a second bindingsource productBindingSource.
So what you need to do is create a bindingsource (let's call it wizardProtocolBindingSource) which you then fill with the data from your protocols table. This becomes the datasource for your combobox column.
The key code looks something like this:
// You bind the datagridview just as before
// this dataset should have the idprotocols field which is your foreign key
// to the protocols table - you will probably want this to be hidden.
bindingSource = new BindingSource();
bindingSource.DataSource = dataSet;
bindingSource.DataMember = "pcap";
dataGridView.DataSource = bindingSource;
// hide the foreign key column
dataGridView.Columns["idProtocols"].Visible = false;
// here we populate your comboboxcolumn binding source
wizardProtocolBindingSource= new BindingSource();
// this dataset is from the protocols table
wizardProtocolBindingSource.DataSource = dataSet;
// Add the combobox column
DataGridViewComboBoxColumn colType = new DataGridViewComboBoxColumn();
colType.HeaderText = "Type";
colType.DropDownWidth = 90;
colType.Width = 90;
colType.DataSource = wizardProtocolBindingSource;
// The DataPropertyName refers to the foreign key column on the datagridview datasource
colType.DataPropertyName = "wizardProtocol";
// The display member is the name column in the column datasource
colType.DisplayMember = "protocolName";
// The value member is the primary key of the protols table
colType.ValueMember = "idprotocols";
// I usually just add the column but you can insert if you need a particular position
dataGridView.Columns.Add(colType);
The above should work for you, though not knowing the names of your dataset columns I had to guess a little.
精彩评论