My Code to Bind ComboBox in windows forms is like this
ddlUsers.DataSource = dsUsers.Tables[0];
ddlUsers.ValueMember = "userID";
ddlUsers.DisplayMember = "Username";
I want to add a deafult Item as first element to this ComboBox, I have tried something like this
ddlUsers.Items.Insert(0, "-Select a user-");
But it throws an error like this.
Items collection cannot be modified when the DataSource property is set.
Can anyone point out correct approach to achieve this?
You have to add row in table this way:
DataRow newRow = dataSet1.Tables[0].NewRow();
newRow["userID"] = 0;
newRow["Username"] = "-Select a User-";
dataSet1.Tables[0].Rows.Add(newRow);
and then give source to combo:
ddlUsers.DataSource = dsUsers.Tables[0];
ddlUsers.ValueMember = "userID";
ddlUsers.DisplayMember = "Username";
For more information refer this MSDN article
Please try this :
DataTable dt = (DataTable)cmbControl.DataSource;
DataRow dr = dt.NewRow();
dr["UserName"] = "---Select User----";
dr["UserID"] = "0";
dt.Rows.InsertAt(dr, 0);
Insert row into datatable and use method InsertAt
You could insert the content of dsUsers.Tables[0] to a List first, add your manual item and then bind that List as DataSource instead of dsUsers.Tables[0] directly.
Insert a new Row at the top.
dr = dsUsers.Tables[0].NewRow();
dr[userID] = "0";
dr[Username] = "-Select a User-";
dsUsers.Tables[0].Rows.InsertAt(dr,0);
And you can set your source as usual
ddlUsers.DataSource = dsUsers.Tables[0];
ddlUsers.ValueMember = "userID";
ddlUsers.DisplayMember = "Username";
Related
I have two forms, in one I fill DataGridView with some rows, each row has two comboboxes.
I am able to get both value and formatted value from these cells, however when I try to copy all of this data into the next DataGridView that is in different form, I am unable to tell him which item from the ComboBox should be marked as selected.
When I was looking around I found these lines of code (unfortunately they were from 6+ years ago)
dataGridView.Rows[index].Cells[3].Value = ImageFormat.Items[1];
(dataGridView.Rows[index].Cells[3] as DataGridViewComboBoxCell).Value = ImageFormat.Items[0];
DataGridViewComboBoxCell comboboxFormat = (DataGridViewComboBoxCell)(dataGridView.Rows[index].Cells[3]);
comboboxFormat.Value = ImageFormat.Items[0];
(dataGridView.Rows[index].Cells[3] as DataGridViewComboBoxCell).Value = (dataGridView.Rows[index].Cells[3] as DataGridViewComboBoxCell).Items[0];
Unfortunately none of these worked and most if not all threw "DataGridViewComboBoxCell value is not valid" exception
Maybe it's worth to mention that the possible items are binded from database like so:
string stm = "SELECT * FROM colours";
using var cmd = new SQLiteCommand(stm, MainWin.con);
SQLiteDataAdapter rdr = new SQLiteDataAdapter(cmd);
DataTable dataTableColour = new DataTable();
rdr.Fill(dataTableColour);
stm = "SELECT * FROM formats";
using var cmdd = new SQLiteCommand(stm, MainWin.con);
SQLiteDataAdapter reader = new SQLiteDataAdapter(cmdd);
DataTable dataTableFormat = new DataTable();
reader.Fill(dataTableFormat);
ImageFormat.ValueMember = "id";
ImageFormat.DisplayMember = "name";
ImageFormat.DataSource = dataTableFormat;
ColourImage.ValueMember = "id";
ColourImage.DisplayMember = "name";
ColourImage.DataSource = dataTableColour;
Your datagridview should be bound to some datatable (let's say ImageFiles). Set ColourImage/ImageFormat combo's .DataPropertyName property to be the name of the column in the [ImageFiles] datatable that the combo should edit. Don't try to interact with the DGVCombo directly; just interact with the datatable to which the grid is bound
I am retrieving a datatable from a Stored Procedure and a Combobox is showing that data but I want to show -Select Program- as default value of Combobox but it is always showing the first record of datatable.
InitializeComponent();
cbxProgram.Items.Insert(0, "-SELECT PROGRAM-");
cbxProgram.SelectedIndex = 0;
cbxProgram.DataSource = SomeBL.GetProgramName().Tables[0];
cbxProgram.DisplayMember = "ProgramName";
cbxType.DataSource = SomeBL.GetType("").Tables[0].DefaultView;
cbxType.DisplayMember = "Type";
cbxNumber.DataSource = SomeBL.GetNumber("", "").Tables[0].DefaultView;
cbxNumber.DisplayMember = "Number";
cbxType.Enabled = false;
cbxType.Enabled = false;
You have to add your custom Row to your Table before binding.
I didn't test this, but it should look something like this:
DataTable dt = SomeBL.GetProgramName().Tables[0];
DataRow dr = dt.NewRow();
dr[0] = "-SELECT PROGRAM-"; // Look at the index of your desired column
dt.Rows.InsertAt(dr,0); // Insert on top position
cbxProgram.DataSource = dt;
cbxProgram.SelectedIndex = 0;
cbxProgram.DisplayMember = "ProgramName";
By using Datasource property, you delete the data exist in the first place. You should insert "-SELECT PROGRAM-" line after you fill the combobox from datasource.
Try this:
cbxProgram.DataSource = SomeBL.GetProgramName().Tables[0];
cbxProgram.DisplayMember = "ProgramName";
cbxProgram.Items.Insert(0, "-SELECT PROGRAM-");
cbxProgram.SelectedIndex = 0;
If it doesn't let you add another line after setting datasource, you may consider adding the line to the source datatable. (I don't recommend adding it from SQL database by changing your stored procedure.)
Check this pseudocode:
SomeBL.GetProgramName().Tables[0].Rows.Add(new DataRow(0, "-SELECT PROGRAM-"));
cbxProgram.DisplayMember = "ProgramName";
cbxProgram.Items.Insert(0, "-SELECT PROGRAM-");
cbxProgram.SelectedIndex = 0;
I have a datagridview that gets populated with data from a database, the last two columns are a combobox and a button.
To prevent flickering I use Rows.AddRange to add all the rows at once (the entire procedure is in a backgroundworker)
My question is how do I add the values to the dropdownbox. The items are just a list of stings so no need to datasource it.
DataTable dt = db.fill(query, dbpars);
DataGridViewComboBoxCell cbox = new DataGridViewComboBoxCell();
cbox.Items.Add("--Please Select--");
cbox.Items.Add("Generate");
cbox.Items.Add("Ignore");
List<DataGridViewRow> rowList = new List<DataGridViewRow>();
foreach (DataRow row in dt.Rows)
{
DataGridViewRow drow = new DataGridViewRow();
drow.CreateCells(dgvClientWork);
drow.Cells[0].Value = row[0];
drow.Cells[1].Value = row[1];
drow.Cells[2].Value = row[2];
drow.Cells[3].Value = row[3];
drow.Cells[4].Value = row[4];
drow.Cells[5].Value = row[5];
//((DataGridViewComboBoxColumn)dgvClientWork.Columns[6]).Items.Add("2");
//var td = new DataGridViewComboBoxCell();
//drow.Cells[6] = td;
//((DataGridViewComboBoxCell) drow.Cells[6]).Items.Add("WFT");
DataGridViewComboBoxCell td = (DataGridViewComboBoxCell)dgvClientWork.Rows[0].Cells[6];
td.Items.Add("--Please Select--");
td.Items.Add("Generate");
td.Items.Add("Ignore");
//td.Items.AddRange(new object[]{"--Please Select--", "Generate", "Ignore"});
//var t = (DataGridViewComboBoxCell)cbox.Clone();
//drow.Cells.Add(t);
//drow.Cells[6] = t;
//drow.Cells[6].Value = "--Please Select--";
/*drow.Cells[7].Value = btn;*/
rowList.Add(drow);
}
Action action = () => dgvClientWork.Rows.AddRange(rowList.ToArray());
dgvClientWork.Invoke(action);
As you can see I have attempted several things but the combobox is always blank.
If I duplicated your problem correctly, if you check the last row in your dgv, that drop down will have multiples of your added items.
To fix, change this line of code:
DataGridViewComboBoxCell td = (DataGridViewComboBoxCell)dgvClientWork.Rows[0].Cells[6];
To this:
DataGridViewComboBoxCell td = (DataGridViewComboBoxCell)drow.Cells[6];
Edit: If you want the cells defaulted, just adding
td.Value = "--Please Select--";
then worked for me.
Edit: On a side note, when you created your DGV and added the columns, I would have just created the ComboBoxColumn and set its DataSource to a list of the same strings you've set in your code. This way any newly added rows by the user will also have the same combobox source. As of right now, any new rows will have empty comboboxes.
I want to add a row in datagridview under my last row which shows summary of the records.So I Fill my dataset and then add a row in it, afterwards I Bind it to a datagridview and then when I try to assign my new row with value it gives me error that cannot convert date time to string as The fourth column datatype is datetime.SO my question is can we change column type of a specific row cell ,If no then how can I achieve what I want to do?
string SelectGroupQuery = "Select * From GroupMembers Where GID=#Id ";
using (SqlConnection conGroup = new SqlConnection(ConnectionString.ToString()))
{
using (SqlCommand commandGroup = new SqlCommand(SelectGroupQuery, conGroup))
{
commandGroup.CommandType = CommandType.Text;
commandGroup.Parameters.Add(new SqlParameter("Id", Id));
SqlDataAdapter da = new SqlDataAdapter(commandGroup);
DataSet ds = new DataSet();
da.Fill(ds);
d1 = new DataGridView();
this.Controls.Add(d1);
d1.Location = new Point(50,y);
d1.Size = new Size(600, 300);
dr = ds.Tables[0].NewRow();
ds.Tables[0].Rows.Add(dr);
d1.DataSource = ds.Tables[0];
d1.Columns[4].ValueType = typeof(string);
d1.Rows[d1.Rows.Count-2].Cells[4].Value = "Total Amount";
y = y + 400;
}
}
Changing the type of a particular cell could be done for some of the column types. See this answer. But I wouldn't recommend it.
It is tricky to use a row in datagridview for displaying summary as it brings in some problems (more when bound to database). You could create your summary row using textboxes outside the datagridview and add the summary data to them. Check this codeproject link for working example.
Instead of assigning the value to the cell, you could fake it by handling the CellFormatting event. If e.ColumnIndex = 4 and e.RowIndex is the last row in the grid, set the formatted value to the label you want and set the property of the EventArgs to tell it you formatted the value.
If you aren't making the whole DataGridView read-only, you probably want to also handle the CellBeginEdit event and cancel the edit if it's the summary row.
I checked on other postings and suggested to make the EnableHeadersVisualStyles = false but that only lets me color them. I want to change their names, but they don't change when I force the name as shown below.
Products prod = new Products();
DataTable dt = prod.GetTopTenTransactions(Global.Instance.Accounts[0]);
transactionGrid.DataSource = dt;
foreach (DataGridViewColumn cols in transactionGrid.Columns)
{
cols.Width = 70;
}
transactionGrid.ColumnHeadersDefaultCellStyle.BackColor = Color.CadetBlue;
transactionGrid.EnableHeadersVisualStyles = false;
transactionGrid.Columns[0].Name = "ID";
transactionGrid.Columns[1].Name = "TYPE";
transactionGrid.Columns[2].Name = "DATE";
transactionGrid.Columns[3].Name = "AMOUNT";
transactionGrid.Columns[4].Name = "FROM";
transactionGrid.Columns[5].Name = "TO";
transactionGrid.Columns[6].Name = "TELLER ID";
Any help would be much appreciated.
DataGridViewColumn.Name is used to identify column in collection.
Try to use DataGridViewColumn.HeaderText instead.
You should use HeaderText property:
transactionGrid.Columns[0].HeaderText = "Header";
If you are using a predefined set of columns (known at design time), then
in visual studio select the datagrid, go to properties
in columns click the ... button
this opens up an extra window, in which you can edit the details of your column
If you are doing things at runtime, then in the code behind file use:
datagrid.Columns[index].HeaderText = "new value";
Hope this helps.