How to edit databound combobox in c# - c#

In my winForm application I have added databound combobox column in a datagridview. User needs to be able to select an item from dropdown list or write in the combobox. But it wouldn't let me write in the combobox as datasource is set. This is my code:
var entityModel= new AdminEntities();
var filterPractice = (from b in entityModel.FILTER where b.PRACTICE != null select b.PRACTICE).Distinct().OrderBy(y => y);
dgvCboColumn(filterPractice, "PRACTICE");
private void dgvCboColumn(dynamic item, string colName)
{
int i = dgvLoadTable.Columns[colName].Index;
DataGridViewComboBoxColumn dgvCol = new DataGridViewComboBoxColumn();
dgvCol.DataSource=item;
dgvCol.DataPropertyName = colName;
dgvLoadTable.Columns.Insert(i, dgvCol);
dgvLoadTable.Columns[i].HeaderText = dgvLoadTable.Columns[i + 1].HeaderText;
dgvLoadTable.Columns[i + 1].Visible = false;
dgvLoadTable.Columns.RemoveAt(i + 1);
}
private void HandleEditShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var cbo = e.Control as ComboBox;
if (cbo == null)
{
return;
}
cbo.DropDownStyle = ComboBoxStyle.DropDown;
cbo.Validating -= HandleComboBoxValidating;
cbo.Validating += HandleComboBoxValidating;
}
private void HandleComboBoxValidating(object sender, CancelEventArgs e)
{
var combo = sender as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
if (!combo.Items.Contains(combo.Text))
{
var comboColumn = this.dgvLoadTable.Columns[this.dgvLoadTable.CurrentCell.ColumnIndex] as DataGridViewComboBoxColumn;
combo.Items.Add(combo.Text);
comboColumn.Items.Add(combo.Text);
this.dgvLoadTable.CurrentCell.Value = combo.Text;
}
}
Can anyone tell me how can I make the combobox editable, please?

you can manually get the items frm datasource using Oledb or Ado recordset nd fill de comboBox manually by using for loops.. so basically you can also edit the items..

Related

C# How to autocomplete specific Gridview column on matching part of any string

I have 3 column Gridview in C# Winform and there are list of drugs in the MS SQL database table.
I want to add autocomplete feature to the second column of the gridview with the data from the drugList table.
It should show the all drugs in the auto complete list, if typed string is included in anywhere in the drugList entry.
This is what I'm trying and it doesn't show any output.
private void gvMedicationsTextBox_TextChanged(object sender, EventArgs e)
{
TextBox textBox = sender as TextBox;
string val = textBox.Text;
cDrugs drug = new cDrugs();
string[] autocompleteList = drug.GetAutoCompleteDrugsList(val);
if (autocompleteList != null)
{
AutoCompleteStringCollection dataCollection = new AutoCompleteStringCollection();
dataCollection.AddRange(autocompleteList);
textBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox.AutoCompleteCustomSource = dataCollection;
}
textBox.Text = val;
}
This is event registration
private void gvMedications_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
TextBox textBox = e.Control as TextBox;
if (textBox != null)
{
textBox.TextChanged += new EventHandler(gvMedicationsTextBox_TextChanged);
}
}
You can add a combobox column to the grid and enable the AutoComplete property so that the selected value will change automatically when anything is written in the cell.

Create custom datagridview's Column type

i just create a custom control, i want this control implement to datagridview's column.
but how? is it possible?
for example, i want add my column type like "DataGridViewCustomTextBoxColumn"
this is my current code.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell.ColumnIndex == 0)
{
Connection.ConnectionClose();
Connection.ConnectionOpen();
var source = new List<string>();
string queryItem = "SELECT * FROM ITEM ";
Connection.command = new OleDbCommand(queryItem, Connection.conn);
Connection.command.CommandType = CommandType.Text;
AutoCompleteStringCollection kode = new AutoCompleteStringCollection();
reader = Connection.command.ExecuteReader();
if (reader.HasRows == true)
{
while (reader.Read())
{
//kode.Add(reader["code"].ToString());
source.Add(reader["code"].ToString());
}
}
else
{
MessageBox.Show("Data not Found");
}
reader.Close();
//ComboBox txtBusID = e.Control as ComboBox;
TextBox kodeTxt = e.Control as TextBox;
if (kodeTxt != null)
{
kodeTxt.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
kodeTxt.AutoCompleteCustomSource = kode;
kodeTxt.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
}
}
what i tried.. like this.
AutoCompleteTextBoxSample.AutoCompleteTextbox kodeTxt = e.Control as AutoCompleteTextBoxSample.AutoCompleteTextbox;
if (kodeTxt != null)
{
kodeTxt.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
kodeTxt.AutoCompleteCustomSource = source;
kodeTxt.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
then my autocomplete is not working anymore
What i want is just like this.
I would use Template Fields for this as described here: https://msdn.microsoft.com/en-us/library/bb288032.aspx
One of the Template Fields will be your custom control.
This will involve writing code, rather than using the GUI.

How do I make three cascading comboBoxes in a DataGridView?

I am a beginner programmer developing a C# WinForms / SQL solution in VS 2015 Professional.
Can anybody please help me with the code below? I am trying to implement cascading comboBoxes inside a DataGridView to do the following:
ComboBox1 lists courses the school has;
ComboBox 2 lists the modules for the selected course;
ComboBox 3 lists the classes for the selected module.
I've googled extensively but nothing I've tried has worked so far... This is so frustrating!
Thank you. I really appreciate your time and help. Here's the code I'm trying:
public partial class Alunos : Form
{
public Alunos()
{
InitializeComponent();
}
BindingSource filteredModulosBS = new BindingSource();
BindingSource filteredTurmasBS = new BindingSource();
private void Alunos_Load(object sender, EventArgs e)
{
this.alunosTableAdapter.Fill(this.bremingtonBackEndDataSet.alunos);
this.alunos_detTableAdapter.Fill(this.bremingtonBackEndDataSet.alunos_det);
this.cursosTableAdapter.Fill(this.bremingtonBackEndDataSet.cursos);
this.modulosTableAdapter.Fill(this.bremingtonBackEndDataSet.modulos);
this.turmasTableAdapter.Fill(this.bremingtonBackEndDataSet.turmas);
DataView dvM = new DataView(bremingtonBackEndDataSet.Tables["modulos"]);
filteredModulosBS.DataSource = dvM;
DataView dvT = new DataView(bremingtonBackEndDataSet.Tables["turmas"]);
filteredTurmasBS.DataSource = dvT;
}
private void alunos_detDataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex == ComboBoxColumnModulo.Index)
{
DataGridViewComboBoxCell dgcbm = (DataGridViewComboBoxCell)alunos_detDataGridView[e.ColumnIndex, e.RowIndex];
dgcbm.DataSource = filteredModulosBS;
this.filteredModulosBS.Filter = "cod_curso='" + this.alunos_detDataGridView[e.ColumnIndex - 1, e.RowIndex].Value.ToString() + "'";
}
if (e.ColumnIndex == ComboBoxColumnTurma.Index)
{
DataGridViewComboBoxCell dgcbt = (DataGridViewComboBoxCell)alunos_detDataGridView[e.ColumnIndex, e.RowIndex];
dgcbt.DataSource = filteredTurmasBS;
this.filteredTurmasBS.Filter = "cod_modulo='" + this.alunos_detDataGridView[e.ColumnIndex - 1, e.RowIndex].Value.ToString() + "'";
}
}
private void alunos_detDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == this.ComboBoxColumnModulo.Index)
{
DataGridViewComboBoxCell dgcbm = (DataGridViewComboBoxCell)alunos_detDataGridView[e.ColumnIndex, e.RowIndex];
dgcbm.DataSource = modulosBindingSource;
this.filteredModulosBS.RemoveFilter();
}
if (e.ColumnIndex == this.ComboBoxColumnTurma.Index)
{
DataGridViewComboBoxCell dgcbt = (DataGridViewComboBoxCell)alunos_detDataGridView[e.ColumnIndex, e.RowIndex];
dgcbt.DataSource = turmasBindingSource;
this.filteredTurmasBS.RemoveFilter();
}
}
}

How to rebind datasource to a winform DataGridView Combobox column?

I have a DataGridView in winform with 2 combo box columns: 1) Companies, 2) Accounts.
I want to update the accounts combo box according to the selected company.
I have this code:
void recipientsDataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
try
{
ComboBox cb = e.Control as ComboBox;
if (cb != null)
{
cb.SelectedValueChanged -= new EventHandler(companyCombobox_SelectedValueChanged);
cb.SelectedValueChanged += new EventHandler(companyCombobox_SelectedValueChanged);
}
}
catch (Exception ex)
{
}
}
private void companyCombobox_SelectedValueChanged(object sender, EventArgs e)
{
try
{
var currentCell = recipientsDataGrid.CurrentCellAddress;
if (currentCell.X == 3)
{
var sendingCB = sender as DataGridViewComboBoxEditingControl;
int companyId = sendingCB.SelectedValue.ToInt();
DataTable dtAccounts = m_CustomersFunctions.GetCompanyAccounts(companyId);
DataGridViewComboBoxCell cboAccounts = (DataGridViewComboBoxCell)recipientsDataGrid.Rows[currentCell.Y].Cells["Account"];
cboAccounts.ValueMember = "account_id";
cboAccounts.DisplayMember = "AccountName";
cboAccounts.DataSource = dtAccounts;
int defaultAccountId = (from row in dtAccounts.AsEnumerable()
where row.Field<string>("AccountName").EndsWith("*")
select row.Field<int>("account_id")).FirstOrDefault();
if (defaultAccountId > 0)
cboAccounts.Value = defaultAccountId;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
It works fine in the first time I select a company, but when I change the company and try to update the data source for the accounts combo box I'm getting an error:
I tried to add the items manualy and not with a DataSource, and I got the same error.
How can I fix it ?
please...
Try to clear the value of accounts cell before rebind it, like this:
private void companyCombobox_SelectedValueChanged(object sender, EventArgs e)
{
try
{
var currentCell = recipientsDataGrid.CurrentCellAddress;
if (currentCell.X == 3)
{
var sendingCB = sender as DataGridViewComboBoxEditingControl;
int companyId = sendingCB.SelectedValue.ToInt();
DataTable dtAccounts = m_CustomersFunctions.GetCompanyAccounts(companyId);
DataGridViewComboBoxCell cboAccounts = (DataGridViewComboBoxCell)recipientsDataGrid.Rows[currentCell.Y].Cells["Account"];
cboAccounts.Value = null; //Add this code
cboAccounts.ValueMember = "account_id";
cboAccounts.DisplayMember = "AccountName";
cboAccounts.DataSource = dtAccounts;
int defaultAccountId = (from row in dtAccounts.AsEnumerable()
where row.Field<string>("AccountName").EndsWith("*")
select row.Field<int>("account_id")).FirstOrDefault();
if (defaultAccountId > 0)
cboAccounts.Value = defaultAccountId;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I had the same problem in vb.net .
Not sure if my solution is good, but it works for me.
Briefly: I create a new temporary "DataGridViewComboBoxCell" object, I assign the "DataSource" and the "Value" (which must belong to "DataSource" !!! otherwise the error "value is not valid" comes out) and assign the new object to correct cell in my "DataGridView" main object, like this:
Dim oDataGridViewComboBox As New DataGridViewComboBox With {
.DataSource = MyDataSource
.Value = MyCorrectValueContainedInDataSource
}
oMyDataGridView.Rows(iLineOfComboBox).Cells("ComboBoxColumnName") = oDataGridViewComboBox
The error "value is not valid" is thrown because the ComboBox value is not included among those present in "DataSource".
P.S.: Sorry, I don't know C# ... but the problem is the same, and I have found this post during a search of solution.

Displaying multiple columns on LookupEdit of Devexpress

I have a DataSource bound to a LookUpEdit. For example I have 2 columns FirstName and LastName and I want to set DisplayMember property to these two columns.
I found that I should subscribe to lookUp_CustomDisplayText() and edit display text property like this:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
LookUpEdit edit = sender as LookUpEdit;
if (e.DisplayText != "")
{
e.DisplayText = e.DisplayText + " " + (string)e.Value;
}
}
but I did not understand what e.Value is and I want to display another column for selected row, not the valuemember of selected row.
This is how I bind the datasource to lookupedit:
private void populateComboBoxForCompanyPerson()
{
lookUpCompanyPerson.Properties.ForceInitialize();
bs = new BindingSource(myDataSet, "CompanyPerson");
lookUpCompanyPerson.Properties.DataSource = bs;
lookUpCompanyPerson.Properties.DisplayMember = "CompanyName";
lookUpCompanyPerson.Properties.ValueMember = "PersonID";
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("PersonID"));
this.lookUpCompanyPerson.Properties.Columns["PersonID"].Visible = false;
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("FirstName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("LastName"));
this.lookUpCompanyPerson.Properties.Columns.Add(new LookUpColumnInfo("CompanyName"));
}
And this is what my datasource looks like:
I've changed Ian O'Brien's code a little bit and it works:
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props;
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
DataRowView row = props.GetDataSourceRowByKeyValue(e.Value) as DataRowView;
if (row != null)
{
e.DisplayText = String.Format("{0} {1}", row["FirstName"], row["LastName"]);
}
}
}
From the DevExpress documentation:
e.Value gets or sets editor's current value.
e.DisplayText gets or sets an editor's display text
The lookup editor's value is obtained from the data source field specified by the RepositoryItemLookUpEditBase.ValueMember property. The GetDataSourceRowByKeyValue method searches for the specified value within this field and returns an object representing the first found record.
The GetDataSourceRowByKeyValue method's return value depends upon the type of the underlying data source. If the data source is a System.Data.DataTable or a System.Data.DataView, this method returns a System.Data.DataRowView object. If the data source is a custom list of items, the appropriate list item is returned.
You want to set the e.Value to the value that you want to display in the control.
private void lookUpCompanyPerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
RepositoryItemLookUpEdit props
if (sender is LookUpEdit)
props = (sender as LookUpEdit).Properties;
else
props = sender as RepositoryItemLookUpEdit;
if (props != null && (e.Value is int))
{
object row = props.GetDataSourceRowByKeyValue(e.Value);
if (row != null)
{
e.Value = String.Format("{0} {1}", (DataRowView)row["FirstName"], (DataRowView)row["LastName"]);
e.Handled = true;
}
}
}
Finally, here are some useful pages with more documentation:
BaseEdit.CustomDisplayText Event
RepositoryItemLookUpEdit.GetDataSourceRowByKeyValue Method
i have use it, just like this;
cmb_tip.Properties.DataSource = _dt;
cmb_tip.Properties.ValueMember = "Value";
cmb_tip.Properties.DisplayMember = "Type";
cmb_tip.Properties.PopulateColumns();
cmb_tip.Properties.Columns["Value"].Visible = false;
This is how it works with LookupEditControl in Version 15.2.7 and a Class:
private void lookUpEditPatients_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
{
var edit = sender as LookUpEdit;
var props = edit.Properties;
var pat = (Patients4ComboBoxVm) props?.GetDataSourceRowByKeyValue(e.Value);
if (pat != null)
{
e.DisplayText = pat.Nachname + ", " + pat.Vorname + "; " + pat.Geburtsdatum + "; " + pat.Versicherungsnummer;
}
}

Categories