Change Textboxcell to a Comboboxcell at run time - c#

I'm using MySQL .net connector to fill a Datagridview using Mysqladapter and Datagridview.Bindingsource. That works good, but I want to change one thing:
In the table which is filled to the DataGridview, there is a column with a text type. The cells in this columns are displayed as a Datagridviewtextboxcell in the datagridview, but I want to change it to DataGridviewComboboxCell (the users should select between ~10 items).
I already tried a lot but nothing worked as it should. The Columns in the DataGridview are readonly, I cannot change DefaultCellTemplate to a DataGridviewComboboxCell, cause it doesn't inherit DataGridviewTextboxcell.
I also tried this: Gridview - convert textboxcell to comboboxcell and back and I think my problem could be solved over this way, but with this solution I have also 1 problem: It doesnt show a DropDown Button.
Any help will be greatly appreciated.

To do this you need to add a new DataGridViewComboBoxColumn to the grid and then hide the text box column.
I show this using code below but you can do the same using the designer (just set the properties I set in code using the designer).
The key things to note are:
DataPropertyName refers to a property of the grid's data source - likely your text box source
You need to provide the column with its own data source
DisplayMember and ValueMember refer to the data source of the column
Here is the code to add the column:
// Here I do this in the form constructor - there are other places you can do it
public Form1()
{
InitializeComponent();
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
// You need to set some properties on the column to make it work
// Datasource is the source (usually a list) of objects to show in the combobox
col.DataSource = dataSource;
col.DataPropertyName = "ColumnInGridDataSource";
col.DisplayMember = "DisplayProperty";
col.ValueMember = "ValueProperty";
dataGridView1.Columns.Add(col);
// This hides the textboxcolumn
dataGridView1.Columns["YourTextBoxColumnName"].Visible = false;
}

In the answer you linked, before the line:
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] = cb;
Try adding:
cb.DisplayStyle = DataGridViewComboBoxDisplayStyle.CHOOSE_ONE;
cb.FlatStyle = FlatStyle.CHOOSE_ONE;
I am not sure how exactly you want to style your comboboxes, so instead of "CHOOSE_ONE", try out the styles and pick the style you want.
Edit: Seems like you're not changing it to a combobox at all. Try this:
var values = new List<string> { "a", "b", "c" };
var cell = new DataGridViewComboBoxCell();
cell.DataSource = values;
dataGridView1[col, row] = cell;

Related

Adding columns to Datagrid

I am adding columns to datagrid and displaying in my application
// Create Datagrid
Mytable = new DataTable("My Table");
// Add Columns
Mytable.Columns.Add(My_Localization.Cultures.Resources.UserId);
Mytable.Columns.Add(My_Localization.Cultures.Resources.Name);
// Fill data
DataRow dr = Mytable.NewRow();
dr[0] = UserId;
dr[1] = Name;
// Add itemsource
DetailsDlg.ItemsSource = Mytable.AsDataView();
Now is it possible to change the columns names when my localization languages changes on the fly? Since columns are added in the code, I am not able to change the column headers. If I put the columns in wpf, then I am not able to add the data before assigning the itemsource. How do I solve this?
Assuming you are binding your datagrid from your code behind and you are not using MVVM.
You can always change your desire column in your code behind, like this:
DetailsDlg.Columns[0].Header = "New column name";

DataGridView prevent auto increasing of id bound column

I have a database with id (identity) column. This column is bound to my DataGridView (WindowsForms). Whenever I add a row to DataGridView (it's not yet added to database, just to DataGridView), number in this column is increasing by one. Extremely annoying behaviour and I don't know how to stop it?
I am not using EF or antyhing similar. Just columns in DataGridView (not automatically generated, but user defined columns - AutoGenerateColumns is switched off), added to DataGridView and with each column set the DataPropertyName.
I don't know your code, but did you try to do this:
datagridview1.AllowUserToAddRows = false;
and make a button for adding the rows , and add it with
datagridview1.Rows.Add(-1,..,...);
Why not just hide the column?
dgvMyDataGridView.Columns["Id"].Visible = false;
I haven't found a way to prevent DataGridView from auto increasing id. But, I could change any value in DataGridView now, with the DataSource being bound to BindingList instead of DataTable, as before (each ComboBoxItem must implement INotifyPropertyChanged).
private void initializeDgvNotesDataSource()
{
List<ComboBoxItem> list = new List<ComboBoxItem>();
BindingList<ComboBoxItem> bindingList = new BindingList<ComboBoxItem>(list);
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = bindingList;
dgvNotes.DataSource = bindingSource;
}
Cast your integer type id column as string before binding to grid. like
select CAST(ID as varchar(100)) as from yourtablename.
You can also set the default value to identify the new record.

datagridview manually filled column value initially not showed

I have an application with multiple datagridviews in a tabcontrol.
One of the tabcontrols has 4 columns that are filled by the datasource.
I don't use autogenerate columns, but use the DataPropertyName to bind values to the columns.
I also have 2 columns i create, wich are filled manually, after assigning the DataSource.
Values in this datagridview are filtered values from a datagridview somewhere else in the application.
When i filter, then go to the tab containing the datagridview, the manual columns are empty.
Changing the filter (but not the results) fills those colums.
How can i get the columns that are manually filled to always show their values?
Calling Refresh() or Update() on the datagridview doesn't solve my problem
Short version of my code:
I actually use a class that inherits from DataGridView
//fill datagridview
PcbLink[] links = Service.Instance.Client.queryPcbLinks();
List<Pcb> pcbs = new List<Pcb>();
foreach (PcbLink link in links)
{
PcbFilter pcbfilter = new PcbFilter();
pcbfilter.pcb_id = link.pcb_id;
Pcb[] res = Service.Instance.Client.queryPcbs(pcbfilter);
pcbs.Add(res[0]);//only first element because pcb_id should always be unique -> only one row
}
cdgvUsage.SetData(pcbs);//setData is used as cdgvUsage.DataSource = pcbs, but does some stuff internally
for (int i = 0; i < links.Length; i++)
{
SortableBindingList<Pcb> dataSource = cdgvUsage.GetData<Pcb>();
cdgvUsage["count", i].Value = links[i].count;
char variantchar = (char)('a' + (char)(dataSource[0].variant));
cdgvUsage.Columns["variant"].ValueType = typeof(string);
cdgvUsage["variant", i].Value = variantchar.ToString();
}
I believe after asigning DataSource to the dataGridView changes must be saved in datasource also otherwise they will not be reflected in the dataGridView (as it takes data from datasource everytime you do Refresh() or Update()).
Make sure manually filled values are stored in dataSource.

Create a gridview programmatically with column and rows RSS

I can not find post that resolve my problem. I saw many times a Add method or Insert method for adding a row but I have not get them !! I work with .NET 4.5
I would like to show you a printscreen in order to demonstrate that I do not dispose these methods, but I can not because I am too novice to have this right :/
I need to create a gridview (not a datagridview) programmatically with one column and several rows. I populate rows manually. If I understand, I must proceed like this : create gridview, then a column that I add to gridview, then a row that I add to column, and then a tablecell that I add to row. Is that the good way to do ?
This is my code :
GridView listTypeBot = new GridView();
// Create my column
BoundField bf = new BoundField();
bf.HeaderText = "Types of bot available";
// Add my column to my gridview
listTypeBot.Columns.Add(bf);
// Create a row and a cell
GridViewRow gvr = listTypeBot.Rows[0]; // I have an exception here : out of range. When I watch my gridview, it does not have row.
TableCell tc = new TableCell();
tc.Text = name;
// Add cell to my row
gvr.Cells.Add(tc);
listTypeBot.Rows[0].Cells.Add(tc);
I think I get this exception because listTypeBot does not have any row. How can I add it please ?
Thanks in advance.
why not just use the DataSource to bind the data in your case the data source is the RSS ? and set AutoGenerateColumns to rue , something like that :
List<string> names = new List<string>();
names.Add(" the alghabban ");
GridView newGrid = new GridView();
newGrid.DataSource = names;
newGrid.DataBind();
and when you need to add row just add it to names and bind the Grid view again

c# datagridview having different datasources for different columns

I have a datagridview which has multiple text columns and a single comboboxcolumn. I need to specify a datasource for the iems of the comboboxcolumn and another datasource for the other text columns. I have tried the following sample code but it does not work.
dgv1.DataSource = DataSet1.Tables[0];
string[] managerList = Array.ConvertAll(DataSet2.Select(), row => (string)row[0]);
comboboxcolumn1.DataSource = managerList;
The managerList array has the entries that are to be populated into the combobox but they never show up.
Is that so that I can not have a separate datasource for a comboboxcolumn and its parent datagridview?
Thanks in advance.
I have checked with the following code and it works fine
string[] arr = "This Should Get Displayed".Split(); //managerList in your case
dataGridView1.DataSource = MyData(false);
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DataSource = new BindingSource(arr, null); // Bind to the column of grid
Can you try assigning it as referencing it as a column of your datagridview.
This displays the text split on space in my combobox.
When you are using string array no need to specify Display and Value member for the column
EDIT
If you have a DataTable you can also do it in this fashion
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DataSource= datatable;
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).DisplayMember="columnname";
(dataGridView1.Columns["Column1"] as DataGridViewComboBoxColumn).ValueMember="columnname";

Categories