For example, I have 100 comboboxes and need to update a particular combobox when it's selected a new index. How can I use only one method to catch the event when there is a combobox set a new value?
Create only one event handler ComboBox_SelectedIndexChanged, and subscribe all the combo boxes to this event:
combobox1.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
combobox2.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
combobox3.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
combobox4.SelectedIndexChanged += ComboBox_SelectedIndexChanged;
//and so on
The event handler code:
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
//now "sender" is the reference to the combo box raised the event
//so just cast it
ComboBox combobox = sender as ComboBox;
//now access it as you want
}
Related
So I was thinking about "if" statement to make it work, but I don't really understand how to connect it to "checked event". I am a beginner so please don't be rough on me
By default, radiobuttons are in a same group. So we can let their CheckedChanged event subscribe to a same method.
public Form1()
{
InitializeComponent();
radioButton1.CheckedChanged += radioButton_CheckedChanged;
radioButton2.CheckedChanged += radioButton_CheckedChanged;
radioButton3.CheckedChanged += radioButton_CheckedChanged;
}
Then use the parameter sender to get the selected radiobutton.
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
// Clear listbox
listBox1.Items.Clear();
// Add the selected radiobutton into listbox
listBox1.Items.Add(((RadioButton)sender).Text);
}
The test result,
I'd like to disable item in ComboBox that is in a DataGridview cell.
I already know how to disable(or seems disabled) items in a ComboBox, using the DrawItem event and SelectedIndexChanged event but there is no similar event in DataGridViewComboBoxCell or DataGridViewComboBoxColumn.
So my question is, how to disable any item in ComboBox that is in a DataGridView?
In ComboBox I can modify items display that need to be disabled like this:
But can't do the same functionality in DataGridView:
I think the simplest option for you would be to handle the EditControlShowing event, and then handle the ComboBoxes SelectedIndexChanged event and do what you already know how to do.
When you setup the DataGridview in code, you can do this:
dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;
And then implement the handler like:
void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if (combo != null)
{
// Both of these lines are essential, otherwise you will be handling the same event twice in some conditions
combo.SelectedIndexChanged -= combo_SelectedIndexChanged;
combo.SelectedIndexChanged += combo_SelectedIndexChanged;
}
}
Finally, the SelectedIndexChanged event is handled exactly the way you want to:
void combo_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox thisCombo = sender as ComboBox;
if (thisCombo != null)
{
Debug.Print(thisCombo.Text);
}
}
I'm surprised I hadn't noticed this before, and couldn't find this question anywhere. Perhaps I'm missing something obvious. When I have the DataSource of a ComboBox set to a BindingList, and I remove an item from the list, the SelectedValueChanged or the SelectedIndexChanged events are not fired, but the SelectedValue does change. Here is the full source to reproduce:
public partial class Form1 : Form
{
public readonly BindingList<string> Items = new BindingList<string>();
public Form1()
{
InitializeComponent();
Items.Add("One");
Items.Add("Two");
Items.Add("Three");
comboBox1.DataSource = Items;
comboBox1.SelectedValueChanged += comboBox1_SelectedValueChanged;
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
button1.Click += button1_Click;
timer1.Interval = 250;
timer1.Tick += timer1_Tick;
timer1.Start();
}
private string GetCurrentText()
{
return comboBox1.SelectedValue as string ?? "NULL";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox1.Text += "Index Changed: " + GetCurrentText() + Environment.NewLine;
}
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
textBox1.Text += "Value Changed: " + GetCurrentText() + Environment.NewLine;
}
private void timer1_Tick(object sender, EventArgs e)
{
Text = GetCurrentText();
}
private void button1_Click(object sender, EventArgs e)
{
Items.Remove((string)comboBox1.SelectedValue);
}
}
All the form has is a ComboBox, a Button, a Timer to keep track of the actual ComboBox's SelectedValue and a multiline TextBox to log the events.
To reproduce, run the form, select the second value ("Two") from the combo box and then press the button. No SelectedValueChanged nor SelectedIndexChanged event will be fired at the button press, but the form's text will show the new value ("Three") given by the timer, which will also be the value shown at the combo box. So the actual selected value will have certainly changed, with no event fired.
Unfortunately there's no SelectedItemChanged event so I don't know how are developers supposed to handle this situation. I'm not sure which other "edge" cases will cause the value to change silently so whatever hacky solution I come up with may not cover every case. I wonder if anyone has came up with a real solution.
This is logically true. After you choose 'Two' ,comboBox1.SelectedIndex = 1. Then you deleted 'Two' item. So 'Three' becomes index '1' from '2', no index changed occur in combo box. No combo's event will fire.
Your second time clicking button will fire combo's events.
I want to bind a ComboBox with checked items from CheckedListBox based on selection made by user.
This is how I bind ComboBox:
private void LoadFOCOutlets()
{
ArrayList outletList = new ArrayList();
Outlet objOutlet = new Outlet();
for (int i = 0; i < customCheckListBoxOutletList.CheckedItems.Count; i++)
{
objOutlet = (Outlet)customCheckListBoxOutletList.Items[i];
outletList.Add(objOutlet);
}
objOutlet.OutletID = 0;
objOutlet.OutletName = "Select Outlet";
outletList.Insert(0, objOutlet);
cmbFOCOutlets.DataSource = outletList;
cmbFOCOutlets.DisplayMember = "OutletName";
cmbFOCOutlets.ValueMember = "OutletID";
cmbFOCOutlets.DropDownStyle = ComboBoxStyle.DropDownList;
}
So, every time when a user check a new item, it should re-bind the ComboBox. The above code works fine.
But which event of CheckedListBox can I use to re-bind the ComboBox after a new item has been checked? I tried using ItemCheck Event. But It doesn't count the current selection.
Any help will be very much appreciated.
Try this event
private void CheckedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//Your code here
}
(Or)
private void CheckedListBox1_ItemCheck(object sender, EventArgs e)
{
//Your code here
}
Refer This
The following is excerpted from
Which CheckedListBox event triggers after a item is checked?
Which CheckedListBox event triggers after a item is checked?
(answer #3)
softburger states:
I tried this and it worked:
(seems to work for me, too)
private void clbOrg_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox clb = (CheckedListBox)sender;
// Switch off event handler
clb.ItemCheck -= clbOrg_ItemCheck;
clb.SetItemCheckState(e.Index, e.NewValue);
// Switch on event handler
clb.ItemCheck += clbOrg_ItemCheck;
// Now you can go further
CallExternalRoutine();
}
The idea is, as mentioned in many posts, CheckedListBox has an ItemCheck event, but no ItemChecked event.
To get around this,
the ItemCheck handler assignment is briefly suspended(within the ItemCheck handler routine itself (!?)),
during which time the CheckedListBox's SetItemCheckState method is invoked for the newly checked item, (which should place the item in the CheckedListBox's CheckedItems collection)
and then the ItemCheck handler is then reassigned.
i.e.
// Switch off event handler
clb.ItemCheck -= clbOrg_ItemCheck;
clb.SetItemCheckState(e.Index, e.NewValue);
// Switch on event handler
clb.ItemCheck += clbOrg_ItemCheck;
and now you can (finally) get all theCheckedListBox Checked Items from its CheckedItems collection. (great hack, if you ask me)
I want to handle the event when a value is changed in a ComboBox in a DataGridView cell.
There's the CellValueChanged event, but that one doesn't fire until I click somewhere else inside the DataGridView.
A simple ComboBox SelectedValueChanged does fire immediately after a new value is selected.
How can I add a listener to the combobox that's inside the cell?
The above answer led me down the primrose path for awhile. It does not work as it causes multiple events to fire and just keeps adding events. The problem is that the above catches the DataGridViewEditingControlShowingEvent and it does not catch the value changed. So it will fire every time you focus then leave the combobox whether it has changed or not.
The last answer about CurrentCellDirtyStateChanged is the right way to go. I hope this helps someone avoid going down a rabbit hole.
Here is some code:
// Add the events to listen for
dataGridView1.CellValueChanged += new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.CurrentCellDirtyStateChanged += new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
// This event handler manually raises the CellValueChanged event
// by calling the CommitEdit method.
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
// This fires the cell value changed handler below
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// My combobox column is the second one so I hard coded a 1, flavor to taste
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[1];
if (cb.Value != null)
{
// do stuff
dataGridView1.Invalidate();
}
}
You can also handle the CurrentCellDirtyStateChanged event which gets called whenever a value is changed, even if it's not commited. To get the selected value in the list, you would do something like:
var newValue = dataGridView.CurrentCell.EditedFormattedValue;
This is the code, which will fire the event of the selection in the comboBox in the dataGridView:
public Form1()
{
InitializeComponent();
DataGridViewComboBoxColumn cmbcolumn = new DataGridViewComboBoxColumn();
cmbcolumn.Name = "cmbColumn";
cmbcolumn.HeaderText = "combobox column";
cmbcolumn.Items.AddRange(new string[] { "aa", "ac", "aacc" });
dataGridView1.Columns.Add(cmbcolumn);
dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox combo = e.Control as ComboBox;
if (combo != null)
{
combo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);
combo.SelectedIndexChanged += new EventHandler(ComboBox_SelectedIndexChanged);
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ComboBox cb = (ComboBox)sender;
string item = cb.Text;
if (item != null)
MessageBox.Show(item);
}
I have implemented another solution, that seems more responsive (e.g.. quicker and less clicks) than Mitja Bonca's above. Although sometimes the combobox closes to quickly. This uses the CurrentCellDirtyStateChanged and CellMouseDown callback
private void myGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (myGrid.CurrentCell is DataGridViewComboBoxCell)
{
myGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
myGrid.EndEdit();
}
}
private void myGrid_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell)
{
myGrid.CurrentCell = myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex];
myGrid.BeginEdit(true);
((ComboBox)myGrid.EditingControl).DroppedDown = true; // Tell combobox to expand
}
}
ComboBox cmbBox = (ComboBox)sender;
MessageBox.Show(cmbBox.SelectedValue.ToString());