Check if Listbox contains a certain element - c#

I know this question was posted here already multiple times but I've read the threads and nothing works for me so I decided to ask here.
I simply want to check if a certain string is already in my listbox. I've tried the
listBox.Items.Contains("stringToMatch")
but I get nothing.
I also tried
foreach (var item in form1.filterTypeList.Items)
{
if (item.ToString() == "stringToMatch")
{
break;
}
He doesn't find anything. Why? How can I solve that?

Try using this way... FindByText
strig toMatch = "stringToMatch";
ListItem item = ListBox1.Items.FindByText(toMatch);
if (item != null)
{
//found
}
else
{
//not found
}

Please try like below. I am doing for loop on List view items to search string based on item tag or item text.
for (int i = 0; i <= ListView.Items.Count - 1; i++)
{
itmX = ListView.Items.Item(i);
if (itmX.Text.ToString() = "stringToMatch")
{
break;
}
}
OR
for (int i = 0; i <= ListView.Items.Count - 1; i++)
{
itmX = ListView.Items.Item(i);
if (itmX.Tag.ToString() = "stringToMatch")
{
break;
}
}

its so simple now , you simply first find the index of that item in the collection of listbox items and then use this fuction of listbox listBox1.FindStringExact .
private void FindMySpecificString(string searchString)
{
// Ensure we have a proper string to search for.
if (searchString != string.Empty)
{
// Find the item in the list and store the index to the item.
int index = listBox1.FindStringExact(searchString);
// Determine if a valid index is returned. Select the item if it is valid.
if (index != ListBox.NoMatches)
listBox1.SetSelected(index,true);
else
MessageBox.Show("The search string did not find any items in the ListBox that exactly match the specified search string");
}
}
visit the following website for more clarification and examples
https://msdn.microsoft.com/en-us/en-en/library/81wes5yz(v=vs.110).aspx

Related

remove split lines by index with same value from list

-from the list an example is 9120038560640 occurs twice or could be more than that.
-lines stored in List<.string> items = File.ReadAllLines(filepath).ToList();
-every line is split in semi colon.
-second index or [1] should compare to all of the lines and remove with found matched.
363193;9120038560640;7,11;9,99 <---- must be remove
363195;9120038560641;9,81;14,99
363194;9120038560640;9,81;14,99 <--- must be remove
363196;9120038560642;9,81;14,99
363197;9120038560643;9,81;14,99
....
..
.
btw. my file has 25,000++ items.
thank you
okay i got the answer and this is working
items = items.Where(x => x.Split(';')[columnIndex] != "").OrderBy(x => x.Split(';')[columnIndex]).ToList();
List<.string> _items = items.ConvertAll(z => z); //I make independent copy
string[] itemsArr = items.ToArray();
int countA = 0;
foreach (string itemArr in itemsArr)
{
List<int> groupDuplicates = new List<int>();
for (int a = countA; a < itemsArr.Count(); a++)
{
if (itemArr != itemsArr[a])
{
if (itemArr.Split(';')[columnIndex] == itemsArr[a].Split(';')[columnIndex]) //if matched then add
{
groupDuplicates.Add(a); // listing index to be remove
}
else
break; //no way to go through the bottom of the list and also to make the performance faster
}
countA++;
}
if (groupDuplicates.Count() != 0)
{
groupDuplicates.Add(groupDuplicates.First() - 1); //I add here the first item in duplicates
foreach (int m in groupDuplicates)
{
_items.Remove(items.ElementAt(m)); //remove by item not by index
}
}
}

Feeding a override value from OnSelectionChangeCommitted DataGridViewComboBoxEditingControl to column object

So I have this and I know it is wrong:
protected override void OnSelectionChangeCommitted(EventArgs e)
{
if (SelectedIndex == 0)
{
GENIO_Viewer.FullColourPaletteForm dlgColour = new GENIO_Viewer.FullColourPaletteForm();
if(dlgColour.ShowDialog() == DialogResult.OK)
{
bool bFound = false;
for(int i = 1; i < Items.Count; i++)
{
ComboboxColourItem ocbItem = (ComboboxColourItem)Items[i];
if(ocbItem.Index == dlgColour.iSelectedColour)
{
SelectedIndex = i;
bFound = true;
break;
// We can just select this one
}
}
if(!bFound)
{
// Add it
ComboboxColourItem ocbItem = ComboboxColourItem.Create((ushort)dlgColour.iSelectedColour);
Items.Add(ocbItem);
SelectedIndex = Items.Count - 1;
}
}
}
base.OnSelectionChangeCommitted(e);
}
This handler is part of my DataGridViewComboBoxEditingControl. But it is the wrong place to add new Items.
I can't workout how to get access to the owning Column as that is where I need to add the Item, otherwise I get exceptions.
I have looked here: https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcomboboxeditingcontrol(v=vs.110).aspx
But i can't see a property I can use to get the column object.
How do we do this from the editing control?
Further explaination:
The list combo items are added by the "column" object. Thus we have a set of 15 colours to choose from. Now I have added a genric colour tot he top of the list.
So, the user invokes the edit, droplist displays, and they pick item 0. We intercept this with the aforementioned handler. Since they picked item 0, we show a popup dialogue to let them choose a different colour.
When they have chosen, we must now either find it or add it to the the mandatory list of items for the column. Make sense now?
I tried to use the DataGridView Notify object but for some reason it is not showing in the list of available functions.
I don't use a DataSource. I populate like this in the columns constructor:
private void InitialiseComboItems()
{
List<ushort> listColours = new List<ushort>();
listColours.Add(0);
listColours.Add(1);
listColours.Add(2);
listColours.Add(3);
listColours.Add(4);
listColours.Add(5);
listColours.Add(6);
listColours.Add(7);
listColours.Add(8);
listColours.Add(9);
listColours.Add(250);
listColours.Add(251);
listColours.Add(252);
listColours.Add(253);
listColours.Add(254);
listColours.Add(255);
this.Items.Clear();
foreach (ushort iColourIndex in listColours)
this.Items.Add(ComboboxColourItem.Create(iColourIndex));
}
I also have a helper method:
public ComboboxColourItem InsertColour(ushort iColourIndex)
{
ComboboxColourItem ocbItem = ComboboxColourItem.Create(iColourIndex);
bool bAppend = true;
if (Items.Count > 16)
{
// There are other colours, need to find right index
for(int i = 16; i < Items.Count; i++)
{
if(ocbItem.Index < ((ComboboxColourItem)Items[i]).Index)
{
bAppend = false;
Items.Insert(i, ocbItem);
break;
}
}
}
if (bAppend)
Items.Add(ocbItem);
return ocbItem;
}
You can use EditingControlDataGridView to find the DataGridView which owns the editing control. Then you can use CurrentCell property of grid to find the current cell and using ColumnIndex you will find the column index. Then using Columns collection, you can get the column at that index:
var c = this.EditingControlDataGridView
.Columns[this.EditingControlDataGridView.CurrentCell.ColumnIndex]
as DataGridViewComboBoxColumn;
if (c != null)
c.Items.Add("Something");

Index was outside the bounds of the array in CheckedListBox

I am getting an index error on my else if statement but I'm unable to find the reason for it.
What I am doing is going through a CheckedListBox, if no values are checked print an error else show the selected values in a MessageBox.
Can anybody help me? Thank you!
for (int i = 0; i < checkedListBox1.Items.Count; i++)
if (checkedListBox1.CheckedItems.Count == 0)
{
Empty.SetError(checkedListBox1, "Please select at Least One");
return;
}
else if (checkedListBox1.GetItemChecked(i))
{
MessageBox.Show(checkedListBox1.CheckedItems[i].ToString());
}
Move the Count-ckeck before the loop:
if (checkedListBox1.CheckedItems.Count == 0)
{
Empty.SetError(checkedListBox1, "Please select at Least One");
return;
}
But the important part is that you are looping all items. Then you check for every item if it is checked with GetItemChecked. That's fine, but then you use checkedListBox1.CheckedItems[i] which doesn't contain all items but only the checked items. That's why you get the Index was outside the bounds error.
Instead you just need to use that collection instead of looping all:
for(int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
{
MessageBox.Show(checkedListBox1.CheckedItems[i].ToString());
}
You should change
i < checkedListBox1.Items.Count;
To:
i < checkedListBox1.CheckedItems.Count;
checkedListBox1.CheckedItems[i] is the problem. You loop through all the items, but indexing CheckedItems. So when you have 10 items and checked 2nd item and 8th item, CheckedItems will have only two items but you'll be accessing CheckedItems[7] that's why you get the exception.
Use CheckedItems collection to access checked items directly.
if (checkedListBox1.CheckedItems.Count == 0)
{
Empty.SetError(checkedListBox1, "Please select at Least One");
return;
}
foreach (var checkedItem in checkedListBox1.CheckedItems)
{
MessageBox.Show(checkedItem.ToString());
}
Why are you checking for CheckedItems.Count inside the for cycle?
Take the first part of the If clause outside of the For cycle.
At the end your code can look like that:
if (checkedListBox1.CheckedItems.Count == 0)
{
Empty.SetError(checkedListBox1, "Please select at Least One");
}
for (int i = 0; i < checkedListBox1.Items.Count; i++)
if (checkedListBox1.GetItemChecked(i))
{
MessageBox.Show(checkedListBox1.Items[i].ToString());
}

Filtering elements of an array

I have an array as
That is, each item has its category in the following index.
I need all the items whose category are TotalNumbers and CurrentNumbers.
I tried
int i = 1;
foreach (string item in statsname)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
{
comboBox1.Items.Add(statsname[i-1]);
i++;
i++;
}
comboBox1.SelectedIndex = 0;
}
Apparently this does not checks for what I need correctly.
How do I need to modify my codes to get what i need ?
Seems it's better to use a for loop instead of foreach:
for (int i = 1; i < statsname.Length; i += 2)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
comboBox1.Items.Add(statsname[i-1]);
}
Linq comes to rescue!
var listItems = from s in statsname where s.Equals("TOTALNUMBER", StringComparison.InvariantCultureIgnoreCase) || s.Equals("CURRENTNUMBER", StringComparison.InvariantCultureIgnoreCase) select new ListItem(s);
comboBox1.AddRange(listItems);
Code not tested or compiled, but you can have an idea of what i said.
var filteredValues = Array.FindAll(source, s => s.ToUpperInvariant() == "TOTALNUMBER" ||
s.ToUpperInvariant() == "CURRENTNUMBER").ToList()
I am not sure why you are using index in an foreach loop. The below code should work for you
foreach (string item in statsname)
{
if ( item.ToUpper() == "TOTALNUMBER" || item.ToUpper() == "CURRENTNUMBER")
{
comboBox1.Items.Add(item);
}
}
comboBox1.SelectedIndex = 0;

How do I determine if multiple items are selected in a ListBox

I think it's obvious what I'm trying to do, but if you don't understand, please ask.
if (listBox1.SelectedIndex == 1 && 2)
{
label1.Text = "Sometext";
}
SelectedIndices is what you want if you have enabled multi-select. You can also check the size of the SelectedItems property.
The documentation for ListBox.SelectedIndex states:
For a standard ListBox, you can use this property to determine the index of the item that is selected in the ListBox. If the SelectionMode property of the ListBox is set to either SelectionMode.MultiSimple or SelectionMode.MultiExtended (which indicates a multiple-selection ListBox) and multiple items are selected in the list, this property can return the index to any selected item.
Try this
if( listBox1.SelectedItems.Count > 1 )
{
// multiple items are selected
}
if (listBox1.SelectedIndices.Count > 1) // I'd use to group all of your multi-selection cases
{
if (listBox1.SelectedIndices.Contains(1) && listBox1.SelectedIndices.Contains(2))
{
label1.Text = "Sometext";
}
}
Keep in mind that the control is 0 based so if you're trying to select the first two options, you'll want to check for 0 (item 1) and 1 (item 2).
edit: modified to handle the requirement listed in comments. Note, there's probably a better way and there may even be a method for this built in (never used the multi-selection list box). But I built a function to handle so you don't have to do it for every scenario.
The function that does the work:
private bool CasesFunction(ListBox lbItem, List<int> validIndices)
{
for (int index = 0; index < lbItem.Items.Count; index++)
{
if (lbItem.SelectedIndices.Contains(index) && !validIndices.Contains(index))
return false;
}
return true;
}
And how I used it:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndices.Count > 1)
{
List<int> MyCase = new List<int> { 0, 1 };
if (CasesFunction(listBox1, MyCase))
{
label1.Text = "Sometext";
return;
}
else
label1.Text = "";
MyCase = new List<int> { 1, 2 }; // can do other checks
if (CasesFunction(listBox1, MyCase))
{
label1.Text = "Sometext 2";
return;
}
else
label1.Text = "";
}
else
label1.Text = listBox1.SelectedIndex.ToString();
}

Categories

Resources