Custom Objects Listbox Foreach Loop - c#

I have a list of postcodeitems and I bind this to a listbox.
It contains two properties : postcode, area.
I want to loop through the listbox items and if the item is selected, add the postcodeitem object to another list.
List<Valueobjects.postcodeitem> temp = _BL.GetPostCodeAreasFromZones();
PCList.AddRange(temp);
ListBox1.DataSource = PCList;
ListBox1.DataBind();
List<Valueobjects.postcodeitem> postcodecollection = new List<Valueobjects.postcodeitem>();
foreach (ListItem listitem in ListBox1.Items)
{
if (listitem.Selected)
{
i = i + 1;
//Run at 20 to speed up query
if (i == 20)
{
//Get data
CustList.AddRange(BL.SearchCustomerByPostcodeArea(postcodecollection,2));
i = 0;
}
else
{
//add the post code to temp list
postcodecollection.Add(listitem);
}
}
}
if (i > 0)
{
//get data
CustList.AddRange(BL.SearchCustomerByPostcodeArea(postcodecollection,2));
}
}
Obviously where I am trying to add (listitem) isnt going to work as this is a list item and not a postcodeitem. My question is how do I get the postcodeitem object within the list where the list item is selected?
thanks

Try something like following.
IList<Employee> boundList = ListBox1.DataSource
var obj = boundList[ListBox1.SelectedIndex]
Update => I have not tested the code but something like following. Using for loop to track the element index.
for (int i = 0; i< ListBox1.Items.Length; i++)
{
if (ListBox1.Items[i].Selected)
{
i = i + 1;
//Run at 20 to speed up query
if (i == 20)
{
//Get data
CustList.AddRange(BL.SearchCustomerByPostcodeArea(postcodecollection,2));
i = 0;
}
else
{
//add the post code to temp list
postcodecollection.Add(ListBox1.DataSource.ToList().ElementAt(i));
}
}
}
if (i > 0)
{
//get data
CustList.AddRange(BL.SearchCustomerByPostcodeArea(postcodecollection,2));
}
}
Anyways this is not recommended way. You should get selected value and use that selected value(unique field) to fetch relevant data from any persistant storage like database.

Related

Trying to change an element in a Collection

I'm trying to modify this code. I need to check for a value in a specific element of FilteredCheckObservable and if true, change the value of another part of that element.
Basically something like
if (FilteredCheckObservable items.Lang = 'ENG')
{items.check = newcheckname;}
Then this will update the sourceGroups Collection.
if (string.IsNullOrEmpty(departmentLine.LineID) || string.IsNullOrEmpty(departmentLine.LineName))
continue;
bool discovered = false;
foreach (var group in sourceGroups)
{
if (!group.Key.Line.IsEqual(departmentLine))
continue;
group.Key.IsDiscovered = true;
discovered = true;
group.Key.ScheduleStatusCount = group.CountGroupItem;
break;
}
if (discovered == false)
{
var _ScheduleItemObservable = new ScheduleItemObservable(departmentLine, MainViewViewModel, Shift.ToString());
var item = new Grouping<ScheduleItemObservable, FilteredCheckObservable>(_ScheduleItemObservable);
if (IsShiftValid)
{
item.Key.Shift = Shift.ToString();
item.Key.IsHistoryEnabled = true;
}
sourceGroups.Add(item);
}
for (int index = 0; index < sourceGroups.Count; index++)
{
if (sourceGroups[index].Key.IsDiscovered == true)
{
foreach (var group in sourceGroups)
{
foreach (FilteredCheckObservable items in group)
{
if (items.Lang_ID == LanguageService.Instance.LanguageType.ToString())
{
sourceGroups.Clear();
sourceGroups.Add(item);
}
}
}
}
}
Welcome Travis,
I would wager the guilty culprit is your foreach loop.
https://stackoverflow.com/a/759985/3403999
You aren't allowed to modify a collection inside of a foreach loop.
I don't know if your collection has an indexer, but if it does, you can convert to a for loop:
for (int i = 0; i < sourceGroups.Count; i++)
{
var group = sourceGroups[i];
// The rest of your code.
I could be wrong. You do say you are trying to modify some existing code. Is it some code that is online? Maybe you could link to it to provide a full context.
Based on your new snippet, you need two for loops:
for (int index = 0; index < sourceGroups.Count; index++)
{
if (sourceGroups[index].Key.IsDiscovered == true)
{
//foreach (var group in sourceGroups)
for (int j = 0; j < sourceGroups.Count; j++)
{
var group = sourceGroups[j];
foreach (FilteredCheckObservable items in group)
{
if (items.Lang_ID == LanguageService.Instance.LanguageType.ToString())
{
sourceGroups.Clear();
sourceGroups.Add(item);
}
}
}
}
}
^ Although that might still be a bad loop. Primarily because you have sourceGroups.Clear();.
What you might be better off doing is creating an internal collection called say 'results'. Do your loop looking for your conditions, and if they meet, add that item to the results collection.
Once your loops terminate, then call sourceGroups.Clear(), and then sourceGroups.AddRange(results). If sourceGroups doesn't have an AddRange, then one final loop of:
foreach (var group in results) { sourceGroups.Add(group); }

multiple drop down boxes not picking up new elements (Selenium, C#)

I have to drop down boxes I am trying to select using Selenium the first one works fine however when i try to select the second it does not pick up the values and still uses the first set of elements.
public static void AnfoldComboBox(string sComboBoxId, string sItemText)
{
Drivers.CurrentDriver.FindElement(By.CssSelector($"#{sComboBoxId} + .anfold-combobox .anfold-combobox-toggle.ui-corner-right")).Click();
IWebElement dropDownWrapper = Drivers.CurrentDriver.FindElement(By.ClassName("anfold-combobox-autocomplete"));
ReadOnlyCollection<IWebElement> items = dropDownWrapper.FindElements(By.CssSelector(".ui-menu-item > div"));
foreach (IWebElement item in items)
{
if (item.Text.Trim() == sItemText)
{
item.Click();
break;
}
}
Can you please try below code and check you are getting completer list from dropdown first ?
SelectElement test = new SelectElement(driver.FindElement(By.CssSelector(".ui-menu-item > div")));
IList<IWebElement> size = test.Options;
int myitem = size.Count;
for (int i = 0; i < myitem; i++)
{
String value = test.ElementAt(i).Text;
Console.WriteLine(value);
if (val.Equals(sItemText, StringComparison.InvariantCultureIgnoreCase))
{
val.click();
}
else{
Console.WriteLine("Not present");
}
}

CheckBoxList loop not working

I'm trying to select values in a CheckBoxList control based on a data source. I have five items in the CheckBoxList and three items in the data source, but in the loop I only get one item selected.
if (ddlUserId.SelectedIndex != 0)
{
RoleDetails rd;
rd = CatalogAccess.GetSingleUserRole(ddlUserId.SelectedValue.ToString());
for (int i = 0; i < cblRoles.Items.Count; i++)
{
cblRoles.Items.FindByValue(rd.RoleID.ToString()).Selected = true;
}
}
I tried this, but it still selects only one item:
RoleDetails rd;
for (int i = 0; i < cblRoles.Items.Count; i++)
{
rd = CatalogAccess.GetSingleUserRole(ddlUserId.SelectedValue.ToString());
if (cblRoles.Items[i].Value == rd.RoleID.ToString())
cblRoles.Items[i].Selected = true;
}
CheckboxList bind code
cblRoles.DataSource = CatalogAccess.GetRoles();
cblRoles.DataTextField = "RoleDetails";
cblRoles.DataValueField = "RoleId";
cblRoles.DataBind();
When you use for loop you need to use index value (Here it is "i"), like
for (int i = 0; i < cblRoles.Items.Count; i++)
{
if(cblRoles.Items[i].Value == rd.RoleID.ToString())
cblRoles.Items[i].Selected = true;
}
Or you can use foreach as below:
Here i have created looping through items of checkbox list using foreach & item will be made selected id its value will match RoleId .
foreach (ListItem li in cblRoles.Items)
{
if (rd.RoleID.ToString() == li.Value)
{
li.Selected = true;
}
else
{
li.Selected = false;
}
}

Getting index for multiple selected item in ListBox in c#

I have two ListBoxes. First ListBox items are list of "Products". and second ListBox items are list of "Item in Product" so When user click the item in first(Product) Listbox The second ListBox will show the list of items in selected Products.
eg:
Products Items in Proucts
AA* 1
BB 2
CC 3
in example above current user selected AA products. And 1,2,3 are the items in product AA.
For the current program,i've done. User only can select One "Products" at a time. Then i want to change to multipleselected. So i want to get index number for each product that user selects, then i can retrieve data from database to get "Items In Products" for all selected products.
if (productsListBox.SelectedItmes.Count >= 0)
{
// please provide me coding here to get index number for each selected items in productListBox.
}
i already getting the answer:
if (productListBox.SelectedItems.Count >= 0)
{
for (int i = 0; i < productListBox.SelectedItems.Count; i++)
{
MessageBox.Show(productListBox.SelectedIndices[i].ToString());
}
}
if (productsListBox.SelectedItmes.Count >= 0)
{
string IDs = string.Empty;
foreach( ListItem li in productsListBox.SelectedItmes )
{
IDs += li.Value+"," ;
}
IDs = IDs.Trim(',');
}
It'll give you a CSV of selected IDs
private string GetTagsList()
{
string Tags = string.Empty;
if (lstTags.SelectedItems.Count >= 0)
{
for (int i = 0; i < lstTags.SelectedItems.Count; i++)
{
Tags += lstTags.SelectedIndices[i].ToString() + ",";
}
Tags = Tags.Trim(',');
}
return Tags;
}

Object reference not set to an instance of an object exception when assigning a list to a listbox

I wrote the following method to load a list box with values that have not been loaded already but I am getting an Object reference not set to an instance of an object exception when assigning the following. Any information would be helpful. Thanks.
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
// Defined outside a method
List<string> cabinetsCurrentNotUsed;
// Set value in the constructor
cabinetsCurrentNotUsed = new List<string>();
Here is the whole procedure.
private void selectCabinetToAdd()
{
// Loop through all server and form cabinet types to see if there are matches
for (int x = 0; x < opticalFile.serverCabinetNames.Count; x++)
{
bool cabinetExists = false;
for (int i = 0; i < opticalFile.CabinetValues.Count; i++)
{
if (opticalFile.serverCabinetNames[x].ToString() == opticalFile.CabinetValues[i].ToString())
{
cabinetExists = true;
}
}
// Add cabinets not used to cabinetsCurrentNotUsed List
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(opticalFile.serverCabinetNames[x].ToString());
}
}
// Send cabinetsCurrentNotUsed List to list box
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
}
You are trying to add a null to the listbox.
Insted of
for (int i = 0; i < cabinetsCurrentNotUsed.Count; i++)
{
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i].ToString());
}
use
foreach (string s in cabinetsCurrentNotUsed)
{
if(s != null)
lbxCabinetName.Items.Add(s);
}
NOTE
This part is not relavant to the question. But in your inner for loop after setting cabinetExists = true; you can break out of the inner loop (if atleast one condition is met you can make sure the cabinetExists is true. you don't have to check for the rest of the items in the inner loop)
EDIT
private void selectCabinetToAdd()
{
foreach (string sc in serverCabinetNames)
{
bool cabinetExists = false;
foreach (string cv in CabinetValues)
{
if (sc == cv)
{
cabinetExists = true;
break;
}
}
if (!cabinetExists)
{
cabinetsCurrentNotUsed.Add(sc);
}
}
foreach (string ccnu in cabinetsCurrentNotUsed)
{
if (ccnu != null)
lbxCabinetName.Items.Add(ccnu);
}
}
Also if your listBox can be null, make sure you check that first before populating the listbox.
if(lbxCabinetName != null)
{
selectCabinetToAdd();
}
EDIT 2
Dynamically adding control
ListBox lbxCabinetName = new ListBox();
lbxCabinetName.Location = new System.Drawing.Point(10, 55);
lbxCabinetName.Size = new System.Drawing.Size(130, 95);
this.Controls.Add(lbxCabinetName);
Strings are nullable so at some point you must be doing something similar to:
cabinetsCurrentNotUsed.Add(null);
Either that or as dbaseman said it is possible lbxCabinetName is null but I'm betting that isn't the case.
As an aside, it's not really a problem but if you're using a generic list of strings the ToString() call isn't necessary. You can just do this:
lbxCabinetName.Items.Add(cabinetsCurrentNotUsed[i]);

Categories