ListBox and Datasource - prevent first item from being selected - c#

Hey. I've got the following code that populates my list box
UsersListBox.DataSource = GrpList;
However, after the box is populated, the first item in the list is selected by default and the "selected index changed" event fires. How do I prevent the item from being selected right after the list box was populated, or how do I prevent the event from firing?
Thanks

To keep the event from firing, here are two options I have used in the past:
Unregister the event handler while setting the DataSource.
UsersListBox.SelectedIndexChanged -= UsersListBox_SelectedIndexChanged;
UsersListBox.DataSource = GrpList;
UsersListBox.SelectedIndex = -1; // This optional line keeps the first item from being selected.
UsersListBox.SelectedIndexChanged += UsersListBox_SelectedIndexChanged;
Create a boolean flag to ignore the event.
private bool ignoreSelectedIndexChanged;
private void UsersListBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (ignoreSelectedIndexChanged) return;
...
}
...
ignoreSelectedIndexChanged = true;
UsersListBox.DataSource = GrpList;
UsersListBox.SelectedIndex = -1; // This optional line keeps the first item from being selected.
ignoreSelectedIndexChanged = false;

Well, it looks like that the first element is automatically selected after ListBox.DataSource is set. Other solutions are good, but they doesn't resolve the problem. This is how I did resolve the problem:
// Get the current selection mode
SelectionMode selectionMode = yourListBox.SelectionMode;
// Set the selection mode to none
yourListBox.SelectionMode = SelectionMode.None;
// Set a new DataSource
yourListBox.DataSource = yourList;
// Set back the original selection mode
yourListBox.SelectionMode = selectionMode;

i using the following, seems to work for me:
List<myClass> selectedItemsList = dataFromSomewhere
//Check if the selectedItemsList and listBox both contain items
if ((selectedItemsList.Count > 0) && (listBox.Items.Count > 0))
{
//If selectedItemsList does not contain the selected item at
//index 0 of the listBox then deselect it
if (!selectedItemsList.Contains(listBox.Items[0] as myClass))
{
//Detach the event so it is not called again when changing the selection
//otherwise you will get a Stack Overflow Exception
listBox.SelectedIndexChanged -= listBox_SelectedIndexChanged;
listBox.SetSelected(0, false);
listBox.SelectedIndexChanged += listBox_SelectedIndexChanged;
}
}

set IsSynchronizedWithCurrentItem="False" and Also SelectedIndex=-1 and every thing should work for you

If you just want to clear the selected value, you can use ClearSelected after you set the DataSource. But if you dont want the event to fire, then you'll have to use one of Joseph's methods.

Perhaps in DataSourceChanged you could check the state of SelectedIndex, if your lucky you could then just force SelectedIndex = -1.

Related

Clear ComboBox if RadioButton is deactivated

I have five RadioButton and five ComboBox controls.
Each RadioButton is connected to a ComboBox.
When I activate one RadioButton, the corresponding ComboBox, it gets enabled.
Now when I choose another RadioButton, the information in the previously selected ComboBox should clear but does not!
I have tried with ComboBox.Clear() as well as ComboBox.Reset(), but it doesn't work.
Here is my code for one of the ComboBox and RadioButton
if (radioButtondinner.Checked == true)
{
comboBoxdinner.DataSource = DList.Dwork();
comboBoxdinner.DisplayMember = "dinner";
}
As I said in comment: you can use one Combobox and only to change data sources when you check other RadioButton that should work sure
But If you want to have more Combobox then just type in else statements
comboBox.DataSource = null;
// create a check change event and use this.
private void radioButtondinner_CheckedChanged(object sender, EventArgs e)
{
if (!radioButtondinner.Checked)
{
// if you want to clear only the text or selected item text
comboBoxdinner.Text = String.Empty;
// if you want to clear the entire data source
comboBoxdinner.DataSource = null;
}
}

DataGridViewComboBoxCell failing to retain choice, auto-selecting item at '0' th index of collection

As clear from the title, my datagridviewComboboxCell, which I am adding to selected cells only, are showing it's dropdown list perfectly, and I can select them seamlessly. Problem arises when the combobox losses focus, it forgets everything about selected item and auto selects the item at index 0, of it's range collection. And many time, a 'DataGridViewDataErrorEvent' is occuring(I traced it by adding DataError event handler). I can not understand what is going wrong to cause the error to fire. Moreover even though I daclare
e.Cancel = false;
in the eventhandler, the ComboBox auto-selects item at index 0.
Plese help me out of this.
N.B . I forgot to add initially(when it appears to screen!), the DataGridViewComboBox has no item selected.
EDIT:-
Code snippet
//Creating and Adding propertiesof DataGridViewComboBoxCell.
RegViewdataGridView.Rows[uniqcustCount].Cells[day].ReadOnly = false; //uniqcustCount & day Are Integers
var pcmbcell = new DataGridViewComboBoxCell();
var tcmbcell = new DataGridViewComboBoxCell();
RegViewdataGridView[day,uniqcustCount] = pcmbcell;
pcmbcell.ReadOnly = false;
pcmbcell.DropDownWidth = 80;
pcmbcell.DataSource = shipdPrdLst;
pcmbcell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
RegViewdataGridView.DataError += RegViewdataGridView_DataError;
void RegViewdataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = false;
}

Deselect combobox item

I have a databound combobox:
using(DataContext db = new DataContext())
{
var ds = db.Managers.Select(q=> new { q.ManagerName, q.ManagerID});
cmbbx_Managers.BindingContext = new BindingContext();
cmbbx_Managers.DataSource = ds;
cmbbx_Managers.DisplayMember = "ManagerName";
cmbbx_Managers.ValueMember = "ManagerID";
}
When the form loads neither item is selected, but when the user chooses an item it cannot be deselected. I tried to add cmbbx_Managers.items.Insert(0, "none"), but it does not solve the problem, because it is impossible to add a new item to the databound combobox.
How do I allow a user to deselect a combobox item?
To add an item to your databound ComboBox, you need to add your item to your list which is being bound to your ComboBox.
var managers = managerRepository.GetAll();
managers.Insert(0, new Manager() { ManagerID = 0, ManagerName = "(None)");
managersComboBox.DisplayMember = "ManagerName";
managersComboBox.ValueMember = "ManagerID";
managersComboBox.DataSource = managers;
So, to deselect, you now simply need to set the ComboBox.SelectedIndex = 0, or else, use the BindingSource.CurrencyManager.
Also, one needs to set the DataSource property in last line per this precision brought to us by #RamonAroujo from his comment. I updated my answer accordingly.
The way you "deselect" an item in a drop-down ComboBox is by selecting a different item.
There is no "deselect" option for a ComboBox—something always has to be selected. If you want to simulate the behavior where nothing is selected, you'll need to add a <none> item (or equivalent) to the ComboBox. The user can then select this option when they want to "deselect".
It is poor design that, by default, a ComboBox appears without any item selected, since the user can never recreate that state. You should never allow this to happen. In the control's (or parent form's) initializer, always set the ComboBox to a default value.
If you really need a widget that allows clearing the current selection, then you should use a ListView or ListBox control instead.
To deselect an item suppose the user presses the Esc key, you could subscribe to the comboxBox KeyDown event and set selected index to none.
private void cmbbx_Managers_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape && !this.cmbbx_Managers.DroppedDown)
{
this.cmbbx_Managers.SelectedIndex = -1;
}
}

CheckedListBox Only One Checked But Keep Last

I am having some difficulty getting a CheckedListBox to behave the way I want it to. What I am trying to accomplish is getting a CheckedListBox with the first box checked on PageLoad. I want only one checkbox checked at any given time but I also don't want the user to uncheck the last checked box. I can do one or the other but I can't seem to do both.
Here is some code snippets that I have used to accomplish the task of having only one checkbox checked. The problem with these are the last selection can be unchecked where there are no checkboxes checked.
1st Snippet:
if(e.NewValue == CheckState.Checked)
{
// Uncheck the other items
for (int i = 0; i < defCheckedListBox.Items.Count; i++)
{
if (e.Index != i)
{
this.defCheckedListBox.SetItemChecked(i, false);
}
}
}
2nd Snippet
// Ensure that we are checking an item
if (e.NewValue != CheckState.Checked)
{
return;
}
// Get the items that are selected
CheckedListBox.CheckedIndexCollection selectedItems = this.defCheckedListBox.CheckedIndices;
// Check that we have at least 1 item selected
if (selectedItems.Count > 0)
{
// Uncheck the other item
this.defCheckedListBox.SetItemChecked(selectedItems[0], false);
}
Here is what I have used to prevent the last checked box to be "unchecked"
if (laborLevelDefCheckedListBox.CheckedItems.Count == 1)
{
if (e.CurrentValue == CheckState.Checked)
{
e.NewValue = CheckState.Checked;
}
}
I know this has got to be simple but I think because I've had a long week and I have looked at this too long it is just not coming to me. Any help with this is super appreciated! If I solve this over the weekend I will be sure to post my solution. BTW Happy Holidays to those here in the States :)
Chris makes a good point in the comments that this feels like you are re-inventing radio buttons but you are almost there with the code you have posted if you really want it to work with a CheckedListBox. I have adapted the code from your 1st Snippet which I think does the trick:
//remove the event handler so when we change the state of other items the event
//isn't fired again.
defCheckedListBox.ItemCheck -= defCheckedListBox_ItemCheck;
if (e.NewValue == CheckState.Checked)
{
// Uncheck the other items
for (int i = 0; i < defCheckedListBox.Items.Count; i++)
{
if (e.Index != i)
{
this.defCheckedListBox.SetItemChecked(i, false);
}
}
}
else
{
//the state was not checked.
//as only one item can ever be Checked inside the event
//handler the state of not checked is invalid for us; set the state back to Checked.
e.NewValue = CheckState.Checked;
}
//re-add the event handler
defCheckedListBox.ItemCheck += defCheckedListBox_ItemCheck;
Essentially the only new parts are the else where we reset the state if the state was not Checked and the removing and re-adding of the event to prevent it firing again when we manually set the state of other items (this could be handled with a global bool if you prefer).
// Use CheckBoxList Event
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
// Stops DeInitialize Event
checkedListBox1.ItemCheck -= checkedListBox1_ItemCheck;
// Get the new value old value my be in Indeterminate State
checkedListBox1.SetItemCheckState(e.Index, e.NewValue);
// Start ReInitialize Event
checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
}

Why selected index change on adding data source?

Whenever we add data source to combobox with code below.
comboBoxBusNo.DataSource = busNo.Tables[0];
comboBoxBusNo.DisplayMember = "BusId";
comboBoxBusNo.ValueMember = "Id";
Why private void comboBoxBusNo_SelectedIndexChanged(object sender, EventArgs e) event is called. How we can stop this to be called at loading.
When you bind a list to a ComboBox, the first item is selected by default, which sets the SelectedIndex to 0. There are no items prior to binding so no item is selected, thus the SelectedIndex is -1 to begin with. The SelectedIndex changes from -1 to 0 so the SelectedIndexChanged event is raised.
This will stop the event from firing on load.
comboBoxBusNo.SelectedIndexChanged -= comboBoxBusNo_SelectedIndexChanged;
comboBoxBusNo.DataSource = busNo.Tables[0];
comboBoxBusNo.DisplayMember = "BusId";
comboBoxBusNo.ValueMember = "Id";
comboBoxBusNo.SelectedIndexChanged += comboBoxBusNo_SelectedIndexChanged;

Categories