Access to value of comboBox on selectedIndexChanged event - c#

I have a comboBox with SelectedItemChanged event. So I want to extract value of selected item like:
private void cboCustomerType_SelectedIndexChanged(object sender, EventArgs e)
{
var db = new SQLConnMgr();
ComboBox cmb = (ComboBox)sender;
var comboSelectedValue = cmb.SelectedItem;
}
Problem is value I want is on cmb.SelectedItem.Row.ItemArray[1]
But I can't access to cmb.SelectedItem.Row. Why I can't do as simple as: cmb.SelectedItem.Row.ItemArray[1]? Regards

Your selected item type is DataRowView so you need to cast SelectedItem to that:
private void cboCustomerType_SelectedIndexChanged(object sender, EventArgs e)
{
// A combobox with nothing selected will have a SelectedIndex of -1
if (cboCustomerType.SelectedIndex > -1)
{
// Cast SelectedItem to DataRowView
DataRowView item = cboCustomerType.SelectedItem as DataRowView;
if (item != null)
{
// Access the data in column 1 of the selected row
string value = item[1].ToString();
}
}
}

I believe you are binding combobox with DataSet. So you can do this:
DataRow dataRow = dataSet.Select(string.Format("FieldName = '{0}'", ComboBox.SelectedValue.ToString()))[0];
if (ComboxBox.SelectedValue != null)
{
// can use fields like
String text = dataRow[“fieldName”].ToString();
}
else
{ //something wrong
}
}

Instead of
ComboBox cmb = (ComboBox)sender;
write
ComboBox cmb = sender as ComboBox;
This way it worked for me.

Related

C# Binding Source Control

I am Developing a winforms application. I have two datagrid views populated from two different bindingsources(control). I am using these to implement the master detail approach. My problem is that when the first datagridview is populated using the binding source I can't select the first row of it ,because the first element in the binding source is defaultly selected and can't be selected. Can any one provide me a solution for this
As you say the first row is selected by default. So after populating the DataSource to your first GridView you can set the second GridView based on first entry. Later you check the selectionChanged Event to populate the second GridView based on selectedRow of your first one.
Code could look sth. like this:
private void PopulateDataSource()
{
dataGridView1.DataSource = myBindingSource;
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
If this doesn't work let me know but should do the job.
UDPATE
Here is a similar example using the events and methods of the bindingSource:
private void Initialize()
{
RegisterBindingSourceEvents();
dataGridView1.DataSource = bindingSource1;
dataGridView2.DataSource = bindingSource2;
bindingSource1.DataSource = myDataSource;
}
private void RegisterBindingSourceEvents()
{
bindingSource1.DataSourceChanged += BindingSource1_DataSourceChanged;
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
private void BindingSource1_DataSourceChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
Further you maybe can use:
bindingSource.MoveNext();
bindingSource.MoveFirst();
To simulate focusing seconde row and directly first row. A bit ugly but i would guess this fires current_changed (untested). Better use first approach.
UDPATE-2
I'm sorry to tell you that this is not possible in a beautiful manner. The problem is that the Current Property of your bindingList is always set if your DataSource contains items. So if the user select the same row as the bindingSource Current Property contains your event won't get called. I found a solution which works in my example. You will need one gridEvent and maybe have to do some improvments but the idea should do the job. Sorry but without gridEvent i can't solve this:
Notice that iam using List as DataSource for my Testcase. You got DataTable and have to cast to DataRowView instead of Dummy for sure.
private bool _automatedRowChange;
private void Initialize()
{
List<Dummy> dummies = new List<Dummy> { new Dummy { Id = 1, Text = "Test1" }, new Dummy { Id = 2, Text = "Test2" } };
bindingSource1.DataSource = dummies;
dataGridView1.DataSource = bindingSource1;
//So the first row isn't focused but the bindingSource Current Property still holds the first entry
//That's why it won't fire currentChange even if you click the first row. Just looks better for the user i guess
dataGridView1.ClearSelection();
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
dataGridView1.CellClick += DataGridView1_CellClick;
}
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
var clickedRow = dataGridView1.Rows[e.RowIndex].DataBoundItem as Dummy;
var currentRow = bindingSource1.Current as Dummy;
if (clickedRow != null &&
currentRow != null &&
clickedRow.Equals(currentRow))
{
_automatedRowChange = true;
bindingSource1.MoveNext();
_automatedRowChange = false; //MovePrevious is based on the click and should load the dataSource2
bindingSource1.MovePrevious();
}
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
if (!_automatedRowChange) //Check if you jump to next item automatically so you don't load dataSource2 in this case
{
//Set the second DataSource based on selectedRow
}
}

ComboBoxCell Value is not valid

I have a datagridview binded to a BindingList and inside this list I have comboboxes binded to a list which is a property of my BindingList, for understanding better:
ListA ---> binded to datagridview
ListA.ListB ---> binded to comboboxes
When I open the form I can corectly set my comboboxes showing the values inside the ListB, but when I add a new item I get an error (value is not valid), here is the code:
private void dataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
((DataGridViewComboBoxColumn)dataGridView.Columns["Names"]).DisplayIndex = 4;
for (int i = 0; i < People.Count; i++)
{
var cell = (DataGridViewComboBoxCell)dataGridView.Rows[i].Cells["Names"];
cell.DataSource = People[i].Names;
cell.Value = People[i].Names[0];
}
}
The code above works great, the problem happens here:
private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (dataGridView.CurrentCell.ColumnIndex != dataGridView.Columns["Names"].Index)
return;
var cell = (DataGridViewComboBoxCell)dataGridViewICAO.CurrentCell;
if (cell.EditedFormattedValue.ToString().Equals(String.Empty)) return;
var regex = new Regex("[a-zA-Z]");
if (!regex.IsMatch(cell.EditedFormattedValue.ToString()))
e.Cancel = true;
else
{
People[cell.RowIndex].Names.Add(cell.EditedFormattedValue.ToString());
cell.Value = People[cell.RowIndex].Names.Last();
People[cell.RowIndex].Names = cell.Value.ToString();
}
}
on the row code cell.Value = People[cell.RowIndex].Names.Last(); I get the exception... Thanks to all!
This is how I set the combobox:
private void AddComboBox()
{
var comboNames = new DataGridViewComboBoxColumn { Name = "cmbNames", HeaderText = "Names" };
dataGridView.Columns.Add(comboNames);
}
private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView.CurrentCell.ColumnIndex == dataGridView.Columns["cmbNames"].Index)
{
var combo = e.Control as ComboBox;
if (combo == null)
return;
combo.DropDownStyle = ComboBoxStyle.DropDown;
}
}

get a specific item in DataGridViewComboBoxCell c#

I have some items in my DataGridViewComboBoxCell, when the form loads i need to show a specific item in that DataGridViewComboBoxCell.
Here is the code-
DataGridViewComboBoxCell cbc = new DataGridViewComboBoxCell();
foreach (String item in objectListBoxList[listboxNumber].GetItemInList())
{
cbc.Items.Add(item);
}
dataGridViewList[tableNumber].Rows[parameter.getRow()].Cells[1] = cbc;
I need it to be something like this---
dataGridViewList[tableNumber].Rows[parameter.getRow()].Cells[1] = cbc.Items[1];
I give you the codes for clicking on specific cell.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
// Show in messagebox
MessageBox.Show(dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString());
// Set the value to string
String value = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()
}
}
This is the answer i coded :
DataGridViewComboBoxCell cbc = new DataGridViewComboBoxCell();
foreach (String item in objectListBoxList[listboxNumber].GetItemInList())
{
cbc.Items.Add(item);
}
// this line sets the default item in DataGridViewComboBoxCell to be at index 0--
cbc.Value = myListBox[0];
dataGridViewList[tableNumber].Rows[parameter.getRow()].Cells[1] = cbc;

Adding ComboBox to Datagridview

I found a way to add a combobox to DataGridview (Winform) cell, but I have not found an event like ItemDataBound of DataGridView to set a value to comboBox. And do not know how to set a selected value of a comboBox to DataItem property of a current row (of a DataGridView) :(
Please give me some clues to do this task
Thanks you so much
You can use below method to add data to a combobox in gridview. If you dont have a list you can add items to the combobox as:
cmbdgv.Items.Add("Test");
private void bindDataToDataGridViewCombo() {
DataGridViewComboBoxColumn cmbdgv = new DataGridViewComboBoxColumn();
List<String> itemCodeList = new List<String>();
cmbdgv.DataSource = itemCodeList;
cmbdgv.HeaderText = "Test";
cmbdgv.Name = "Test";
cmbdgv.Width = 270;
cmbdgv.Columns.Add(dgvCmbForums);
cmbdgv.Columns["Test"].DisplayIndex = 0;
}
After adding if you want to capture the combobox selection change you can use below event in the datagridview.
ComboBox cbm;
DataGridViewCell currentCell;
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
cbm = (ComboBox)e.Control;
if (cbm != null)
{
cbm.SelectedIndexChanged += new EventHandler(cbm_SelectedIndexChanged);
}
currentCell = this.dataGridView1.CurrentCell;
}
}
void cbm_SelectedIndexChanged(object sender, EventArgs e)
{
this.BeginInvoke(new MethodInvoker(EndEdit));
}
void EndEdit()
{
if (cbm != null)
{
string SelectedItem=cbm.SelectedItem.ToString();
int i = dataGridView1.CurrentRow.Index;
dataGridView1.Rows[i].Cells["Test"].Value = SelectedItem;
}
}
If you are trying to set the value to a Combobox in a DataGridView, see if this answer will help.
To get the selected item of the Combobox (example):
comboBox.SelectedIndexChanged += new EventHandler(comboBox_ComboSelectionChanged);
private void comboBox_ComboSelectionChanged(object sender, EventArgs e)
{
if (myDGV.CurrentCell.ColumnIndex == 5)
{
int selectedIndex;
string selectedItem;
selectedIndex = ((ComboBox)sender).SelectedIndex; // handle an error here.
// get the selected item from the combobox
var combo = sender as ComboBox;
if (selectedIndex == -1)
{
MessageBox.Show("No value has been selected");
}
else
{
// note that SelectedItem may be null
selectedItem = combo.SelectedItem.ToString();
if (selectedItem != null)
{
// Your code

how to allow user manual entry in datagridview combobox in c#

I am trying to enter values in a datagridview Combobox. but it does not Allows. What to do?
private void GridStockItemEntry_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
DataGridViewRow row = GridStockItemEntry.CurrentRow;
DataGridViewCell cell = GridStockItemEntry.CurrentCell;
if (e.Control.GetType() == typeof(DataGridViewComboBoxEditingControl))
{
if (cell == row.Cells["ItemName"] && Convert.ToString(row.Cells["Type"].Value) == "Raw Material")
{
DataGridViewComboBoxEditingControl cbo = e.Control as DataGridViewComboBoxEditingControl;
cbo.DropDownStyle = ComboBoxStyle.DropDown;
cbo.Validating += new CancelEventHandler(cbo_Validating);
}
}
}
void cbo_Validating(object sender, CancelEventArgs e)
{
DataGridViewComboBoxEditingControl cbo = sender as DataGridViewComboBoxEditingControl;
DataGridView grid = cbo.EditingControlDataGridView;
object value = cbo.Text;
// Add value to list if not there
if (cbo.Items.IndexOf(value) == -1)
{
DataGridViewComboBoxCell cboCol = (DataGridViewComboBoxCell)grid.CurrentCell;
// Must add to both the current combobox as well as the template, to avoid duplicate entries...
cbo.Items.Add(value);
cboCol.Items.Add(value);
grid.CurrentCell.Value = value;
}
}
Maybe, this example is better readable:
private void datagridview_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
DataGridView dgv = (DataGridView)sender;
if(dgv.CurrentCell.ColumnIndex==dgv.Columns["ColumnName"].Index) {
ComboBox cbx = (ComboBox)e.Control;
cbx.DropDownStyle = ComboBoxStyle.DropDown;
cbx.AutoCompleteSource = AutoCompleteSource.ListItems;
cbx.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
}
}
Make sure that EditMode property of the DataGridView is set to EditOnKeystrokeOrF2
Also, verify that ReadOnly property is set to False.

Categories

Resources