Avoid calling indexchanged event when filling datasoruce - c#

I'm filling a combobox with the datasource property in a c# winform app. In the other hand, I'm firing up an action with the SelectedIndexChanged of the same combo. The problem is that whenever the combo is filled with datasource the SelectedIndexChanged is called and I just want this event to be called when the user in fact does a selection.
Is there a way to avoid calling this event when filling the combo?
This is some of my code
//Filling the combo with some data
combo_cliente.DataSource = clientes;
combo_cliente.DisplayMember = "NomComp";
combo_cliente.ValueMember = "IDPersona";
private void combo_cliente_SelectedIndexChanged(object sender, EventArgs e)
{
// Here is the action to be triggered when user perfoms a selection
}
Thanks

Maybe unsubscribe and then subscribe again:
combo_cliente.SelectedIndexChanged -= combo_cliente_SelectedIndexChanged;
combo_cliente.DataSource = clientes;
combo_cliente.SelectedIndexChanged += combo_cliente_SelectedIndexChanged;

im assuming you assigned the event handler with the designer so they are bound when the control is instantiated. alternatively you could assign them in code after populating the controls.

Attach your event handler in your code behind instead of doing it on your aspx page and do it affer you have finished loading your control.

you need to add a blank record as the first of your combobox. Then in your code, you can write this;
private void combo_cliente_SelectedIndexChanged(object sender, EventArgs e)
{
if!(comboBox1.SelectedValue.ToString()== string.Empty)
{
//Here is the action to be triggered when user perfoms a selection
}
}

Related

WinForms SelectedIndexChangeCommitted not firing

I'm populating a combobox from a datasource and I have code for when the user changes the selection in the combobox. So obviously I don't want the code in the SelectedIndexChanged method to fire on form load.
This SO question was answered by suggesting two things:
1) Before and after loading the data to the combobox use this code:
private void LoadYourComboBox()
{
this.comboBox1.SelectedIndexChanged -= new EventHandler(comboBox1_SelectedIndexChanged);
// Set your bindings here . . .
this.comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_SelectedIndexChanged);
}
I tried that with this code:
this.cboSelectCategory.SelectedIndexChanged -= new EventHandler(cboSelectCategory_SelectedIndexChanged);
However, the cboSelectCategory_SelectedIndexChanged part has a red error squiggly and hovering over it says: The name cboSelectCategory_SelectedIndexChanged does not exist in the current context. I tried that code in both the form_load and the method that actually populates the combobox.
2) That same SO question had the answer to use the event SelectedIndexChangeCommitted.
private void cboSelectCompany_SelectedIndexChangeCommitted(object sender, EventArgs e)
{
string selectedCat = cboSelectCategory.SelectedValue.ToString();
Console.WriteLine(selectedCat);
}
But that event isn't firing when I change the selection in the combobox.
Am I missing something somewhere? Is my code off or in the wrong place?
So obviously I don't want the code in the SelectedIndexChanged method to fire on form load.
If you bind your combobox in the form's constructor (after InitializeComponent()) then SelectedIndexChanged will fire before the form is visible, so you can simply return from the selectedindexchanged event if the form is invisible:
public MainForm()
{
InitializeComponent();
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Code");
dt.Rows.Add("Milk", "MLK");
dt.Rows.Add("Bread", "BRD_WHITE");
dt.Rows.Add("Bread", "BRD_BROWN");
dt.Rows.Add("Coffee", "COFF");
comboBox1.DataSource = dt;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Code";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (!this.Visible)
return;
MessageBox.Show("a");
}
It's often easier to simply return from an event handler at an unwanted time than to mess around trying to remove and add event handlers
Side note: If you use a strongly typed dataset and create the bindings using the windows forms designer, the event doesn't fire, I believe because the forms designer InitializeComponent() calls Begin/EndInit on the components at the start and end

Is it possible to fire EditValueChanged event in CheckedComboBoxEdit control immediately after the item has been checked

I need to update the edit value of the CheckedComboBoxEdit control immediately after the item has been checked
The MouseUp event can be used to trigger EndEditwhich will commit the change slightly faster.
I used this to solve my simular issue when working with a CheckBox within a DateGridView. As by default the event to submit changes in a DataGridView only fires when leaving the cell.
You should subscribe Popup event of CheckedComboBoxEdit, find CheckedListBoxControl and subscribe ItemCheck event. Like this:
void _orgStructEntitesCheckedComboBoxEdit_Popup(object sender, EventArgs e)
{
var popup = (IPopupControl)sender;
var control = popup.PopupWindow.Controls.OfType<PopupContainerControl>().First().Controls.OfType<CheckedListBoxControl>().First();
control.ItemCheck += control_ItemCheck;
}
void control_ItemCheck(object sender, DevExpress.XtraEditors.Controls.ItemCheckEventArgs e)
{
var checkedListBoxControl = (CheckedListBoxControl)sender;
var current = checkedListBoxControl.Items[e.Index];
}
Use e.Index to get current item changed.
More information here and here.

Executing an action only when I select an item form the combo box

I have a ComboBox and in the form's load event it's populated with data. Now when I select an Item form the ComboBox, it should perform some actions. So I know few events which can be used in this case like
SelectedIndexChanged
SelectedValueChanged
etc.
But the problem is those events are raised even when setting the DataSource of the ComboBox and selecting a default index etc. when the form is loaded.
ComboBox1.DataSource = dt;
ComboBox1.SelectedIndex = -1;
What am I trying to do is that I just want to execute an action only when I select an item form the combo box. Is there a mouse event that could be used in this case?
The comboBox.SelectionChangeCommitted Event seems to do that.
Otherwise you could set a boolean value before you bind the datasource which you can use inside the event to ignore it.
private bool blnIgnoreEvent = false;
// in Form_load
blnIgnoreEvent = true;
ComboBox1.DataSource = dt;
blnIgnoreEvent = false;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (!blnIgnoreEvent)
{
// go ahead
}
}
I don't believe there is another event that better handles what you'd like to do. XIVSolutions has a neat work-around for the event firing when you bind the data source: How to prevent selectedindexchanged event when DataSource is bound?
Also, since SelectedIndexChanged works for all cases, why not just handle the first?
if (ComboBox1.SelectedIndex == -1)
{
return;
}
If -1 corresponds to a value you'd like to be able to select, just use a private field to store some bool that you check to determine whether or not it is the first time the action has been executed.

C# combobox appropriate event type

I have a combobox and with this I have a associated event
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
}
My comobox is populated with two items a and b
I am setting combobox8.selectedItem = x where x= a or b. My event only fires if I select a from b or b from a. It does not fire if I again select a from a.
How can I do it and what's the appropriate event to deal with it ?
Moreover I am doing it all programmatically.
It makes sense that the event doesn't fire again. The selected item doesn't change. Depending on what you actually want, there are a lot of events you can utilize. You might start with Click, or DropDown, or DropDownClosed, for instance.
It won't fire because Selected Index did not change...
Take a look at msdn documentation for a list of comboBox events:
http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox_events.aspx
You'll find out you can use more one depending on what you want to achieve (leave,lostfocus, [...])
Because the index did not change, the event is not fired. Since you need this processing when you are refreshing the form programmatically, call the appropriate code programmatically as well:
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
ProcessComboBoxInput();
}
private void RefreshFormProgrammatically()
{
// Refresh the form here...
ProcessComboBoxInput();
}
private void ProcessComboBoxInput()
{
// Process the comboBox8 here...
}
Because its selected index changed event. From a to a nothing has been changed. You can try onclick event.

Modifying ComboBox SelectedIndex Without Triggering Event in C#

My C# application has a comboBox with a SelectedIndexChanged event. Usually, I want this event to fire, but but sometimes I need the event to not fire. My comboBox is an MRU file list. If a file in the list is found to not exist, the item is removed from the comboBox, and the comboBox SelectedIndex is set to zero. However, setting the comboBox SelectedIndex to zero causes the SelectedIndexChanged event to fire, which in this case is problematic because it causes some UIF code to be run in the event handler. Is there a graceful way to disable/enable events for C# form controls? Thanks.
Start the eventhandler method with
ComboBox combo = sender as ComboBox;
if (combo.SelectedIndex == 0)
{
return;
}
If you're issue is with a different eventhandler you could remove the eventhandler's event registration first.
combo.SelectedIndexChanged -= EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;
combo.SelectedIndex = 0;
combo.SelectedIndexChanged += EventHandler<SelectedIndexChangedEventArgs> SomeEventHandler;
I have encountered this many times over the years. My solution is to have a class level variable called _noise and if I know I am about to change the index of combo or any other similiar control that fires when the selected index changes, I do the following in code.
private bool _noise;
Here is the code for the control event handler
private void cbTest_SelectedIndexChange(object sender, EventArgs e)
{
if (_noise) return;
// process the events code
...
}
Then when I know I am going to change the index, I do the following:
_noise = true; // cause the handler to ignore the noise...
cbTest.Index = value;
_noise = false; // let the event process again
I'm surprised there isn't a better way of doing this, but this is the way I do it. I actually use the Tag field of most controls so I don't have to subclass the control. And I use true/null as the values, since null is the default.
Of course, if you are actually using Tag, you'll need to do it differently...
In handler:
private void control_Event(object sender, EventArgs e)
{
if (control.Tag != null ) return;
// process the events code
...
}
In main code
try
{
control.Tag = true;
// set the control property
control.Value = xxx;
or
control.Index = xxx;
or
control.Checked = xxx;
...
}
finally
{
control.Tag = null;
}
One (fairly ugly) way would be to set a flag in the code that deletes the entry and then check that in the SelectedIndexChanged handler:
if (!deletedEntry)
{
// Do stuff
}
deletedEntry = false;
A better way might be to remove your SelectedIndexChanged event handler at the start of the delete method and reinstate it at the end. This way you code won't know the index has changed.
There's a better way!
combo_box = QComboBox() # your combobox
combo_box.blockSignals(True)
combo_box.setCurrentIndex(self, ix)
combo_box.blockSignals(False)

Categories