I have the following code.
I am trying to insert values into a listbox, and then be able to resort the values by alphabetical order and re display them in the same listbox. For some reason code doesn't work (no errors - just when i push the button the listbox clears)
protected void sortButton_Click(object sender, ImageClickEventArgs e)
{
string[] movieArray = new string [cartListBox.Items.Count];
for (int i = 0; i < cartListBox.Items.Count; i++)
{
movieArray[i] = cartListBox.Items[i].ToString();
}
Array.Sort(movieArray);
cartListBox.Items.Clear();
for (int i = 0; i < cartListBox.Items.Count; i++)
{
cartListBox.Items.Add(movieArray[i].ToString());
}
}
I think problem is in last loop.
Do that like follows:
cartListBox.Items.Clear();
for (int i = 0; i < movieArray.Length; i++)
{
cartListBox.Items.Add(movieArray[i].ToString());
}
When you are clearing cartListBox.Items.Clear();, it should not be taken for loop counter like, for (int i = 0; i < cartListBox.Items.Count; i++)
cartListBox.Items.Count was creating problem.
You can avoid all that looping, and your bug, by doing this in a more modern way:
var items = cartListBox.Items
.Select(item => item.ToString())
.OrderBy(x => x);
cartListBox.Items.Clear();
cartListBox.Items.AddRange(items);
cartListBox.Items.Count // is 0 length
you are doing in the previous step:
cartListBox.Items.Clear();
To add movieArray to listbox use AddRange
carListBox.Items.AddRange(movieArray);
To sort just set sorted =true
carListBox.Sorted=true;
Complete code is below
carListBox.Items.AddRange(movieArray);
carListBox.Sorted=true;
Related
I am new to C# and I have encountered an error stating that: InvalidArgument=Value of '2' is not valid for 'index'.
I want to set the items in checkedlistbox checked if there is a match in listbox.
Can anyone help me with this problem.
This the part of my code where the problems appear.
for (int i = 0; i < checklistbox.Items.Count; i++)
{
if (checklistbox.Items[i].ToString() == listbox.Items[i].ToString())
{
//Check only if they match!
checklistbox.SetItemChecked(i, true);
}
}
You just need to use nested for loop. Here is the code.
for (int i = 0; i < listbox.Items.Count; i++)
{
for (int j = 0; j < checkedlistbox.Items.Count; j++)
{
if (listbox.Items[i].ToString() == checkedlistbox.Items[j].ToString())
{
//Check only if they match!
checkedlistbox.SetItemChecked(i, true);
}
}
}
The reason you are getting this error is because you are looping through the count of checklistbox items. So, for example if there are 3 items in that array, and listbox only has 2 items, then on the third loop (when i = 2), you are trying to reference an item in the listbox array that does not exist.
Another way to do it would be like this:
foreach (var item in listbox.Items)
{
if (Array.Exists(checklistbox.Items, lbitem => lbitem.ToString() == item.ToString()))
{
//They match!
checklistbox[item].MarkAsChecked()
}
}
Update: answer updated to add MarkAsChecked() and loop through user inputted values held within checklist array.
I am just looking to know this to try and clean up my code, and also for future reference.
I have a number of textBoxes.
tbPart1.Clear();
tbPart2.Clear();
tbPart3.Clear();
tbPart4.Clear();
tbPart5.Clear();
tbPart6.Clear();
tbPart7.Clear();
Is there any way I could use a loop to replace the numbers?
I tried this, but have no idea how i could run the string.
for (int i = 1; i == 7; i++)
{
string p = "tbPart" + i.ToString() + ".Clear";
}
Inside of the form's code (i.e. in a button click event handler), you can enumerate through all of the TextBox controls on the form and perform a specific action on them:
this.Controls.OfType<TextBox>().ToList().ForEach(x => x.Clear());
If you need to only clear some of the TextBox controls, you can provide a sort of filter like so:
this.Controls.OfType<TextBox>()
// Add a condition to clear only some of the text boxes - i.e. those named "tbPart..."
.Where(x=>x.Name.StartsWith("tbPart"))
.ToList().ForEach(x => x.Clear());
No, you cannot do it that way. But you can define an array or list where you put the controls and then clear them. For example:
List<TextBox> textboxes = new List<TextBox>();
textboxes.Add(tbPart1);
textboxes.Add(tbPart2);
textboxes.Add(tbPart3);
...
Then when you want to clear them
foreach (var tb in textboxes)
tb.Clear();
TextBox[] boxes = new [] {
tbPart1,
tbPart2,
tbPart3,
tbPart4,
tbPart5,
tbPart6,
tbPart7
};
for (int i = 0; i < boxes.Length; i++)
{
boxes[i].Clear();
}
i think you should use an array of textbox then you can do a loop depends the count of numbers of textboxes.
foreach(Control ctrl in this.Controls)
{
if(ctrl.GetType() == typeof(TextBox))
{
ctrl.Text = String.Empty;
}
}
Answer number one by using Control name inside panel1
private void button2_Click(object sender, EventArgs e)
{
string currentCtrlName;
for (int i = 0; i < panel1.Controls.Count; i++)
{
currentCtrlName = "textBox" + (i+1).ToString();
panel1.Controls[currentCtrlName].Text = "";
}
}
==================
Answer number one by using Control index as a child inside panel1
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < panel1.Controls.Count; i++)
{
panel1.Controls[i].Text = "";
}
}
==================
So, I have a listbox with x number of items. On top of the listbox I have a TextBox (this is the search field). I try do develop an algorithm that removes items from the listbox, if it doesn't contain the searchword (variable keyword in the code). This is supposed to happen for each key the user types (on-the-fly). So, the code:
private void _keywordTextBox_TextChanged(object sender, EventArgs e)
{
string keyword = _keywordTextBox.Text;
if (keyword == searchtext || isSpace) // do nothing if space is typed - searchtext is a templatetext in the textbox ("type here to search...")
return; // ignore
else if (keyword == "")
{
listBox.Items.Clear();
foreach (string s in originalList)
listBox.Items.Add(s);
}
else
{
List<string> selection = new List<string>();
foreach (string s in originalList) // originalList is the listbox at startup
selection.Add(s);
listBox.BeginUpdate();
string[] keywordSplit = keyword.Split(' ');
try
{
for (int i = originalList.Count - 1; i >= 0; i--)
{
string[] selectionSplit = selection[i].Split(' ');
int l = 0; // number of hits
for (int j = 0; j < selectionSplit.Length; j++)
{
for (int k = 0; k < keywordSplit.Length; k++)
{
if (selectionSplit[j].ToLower().Contains(keywordSplit[k].ToLower()))
{
l++;
break;
}
}
}
if (l < keywordSplit.Length) // Not hit on all keywords
selection.RemoveAt(i);
}
}
finally
{
listBox.Items.Clear();
foreach (string s in selection) // Add selection in listbox
listBox.Items.Add(s);
if (listBox.Items.Count > 0)
listBox.SetSelected(0, true); // Select first item in listbox
listBox.EndUpdate();
}
}
}
The problem is hard to describe, other than it doesn't work as intended. The behavour is, as far as I can see, sporadic.
If I search for "ck flow", I should get a hit for stackoverflow. More importantly, it should also work if I deletes chars (delete key of backspace). Anybody?
Edit: more details:
The listbox should shrink and grow on each keystroke, based on what the user searches for. The listbox should keep every item that matches the keyword typed in by the user, and filter away that doesn't match.
Or you could try to work out a Regular Expression:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string keyword = textBox1.Text;
if (string.IsNullOrEmpty(keyword.Trim()))
{
listBox1.Items.Clear();
listBox1.Items.AddRange(_originalList.ToArray());
}
else
{
Regex regex = new Regex(GetRegexPatternFromKeyword(keyword));
List<string> selection =
_originalList.Where(s => regex.IsMatch(s)).ToList();
listBox1.Items.Clear();
listBox1.Items.AddRange(selection.ToArray());
}
}
private static string GetRegexPatternFromKeyword(string keyword)
{
string[] words =
keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(word => "(?=.*" + word.Replace(")", #"\)") + ")").ToArray();
return string.Join("", words);
}
disclaimer: there could be some cases where an input would 'destroy' the regex pattern
Your code increases l too often. For instance;
the text 'aaa aaa aaa' with searchword 'aaa bbb' will give an l of 3 because every time you find 'aaa' you increase l. So this will be a match even though 'bbb' is never found.
You can fix this (among others) by deleting found parts of keywordsplit and recreating keywordsplit anew before every search of a new selectionline.
l++;
break;
becomes
l++
keywordSplit.RemoveAt[k];
break;
and move
string[] keywordSplit = keyword.Split(' ');
to just before you start the k loop
Altough I feel there might be better ways to achieve what you want with a bit cleaner and faster code it should work.
I got it to work. #IvoTops helped me in the right direction. Just loop trough all the keyword first, and then the selections.
for (int j = 0; j < keywordSplit.Length; j++)
{
for (int k = 0; k < selectionSplit.Length; k++)
{
if (selectionSplit[k].ToLower().Contains(keywordSplit[j].ToLower()))
{
l++;
break;
}
}
}
Seems to work ok now.
i have lot of pictureboxes named this way: PBr1_1, PBr1_2, ... PBr1_9
I'd like to make loop
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1"){ "PBr1_"+"i".Tag = "cb.png";}
}
so for i=0 => PBr1_0, i=10 => Pbr1_10.
Example i have value in textbox: 0001011101 - then if value in textbox is "1" then i'd like to change picturebox tag.
How to automate this process, using for example loop "for"?
I suppose your controls are on a WinForm (this) and the ones with that name are all pictureboxes.
If so, that's the way ----
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1")
{
Control[] c = this.Controls.Find("PBr1_" + i.ToString(), true);
if(c != null && c.Length > 0) c[0].Tag = "cb.png";
}
}
You can put the picture boxes in to a List<PicutreBox> and iterate over the list.
var pictures = new List<PictureBox>();
pictures.Add(pic1);
pictures.Add(pic2);
//...
for (int i = 0; i < 10; i++)
{
if (Textbox.Text[i].ToString() == "1")
pictures[i].Tag = "cb.png";
}
Dynamic variable names as in your example are not supported.
Create an array (or list) that contain the picture boxes and use those within the for loop.
You can also use reflection but in my opinion it is best not to use that in this case.
If you are using WinForm you can use Control.Find method to locate a control by name
Once you have got the control you can easily change any property
I want to remove whole ListviewItems in my Listview except first Column. I have got a method but it sometimes throw ArgumentRangeException that i could not find why.
private void ListViewClear()
{
for (int i = 0; i < lstKullanicilar.Items.Count; i++)
{
if (lstKullanicilar.Items[i].SubItems.Count != 1)
{
lstKullanicilar.Items[i].SubItems.RemoveAt(1);
lstKullanicilar.Items[i].SubItems.RemoveAt(2);
lstKullanicilar.Items[i].SubItems.RemoveAt(3);
lstKullanicilar.Items[i].SubItems.RemoveAt(1);
lstKullanicilar.Items[i].SubItems.RemoveAt(1);
}
}
Try somethin like this:
for (int i = 0; i < lstKullanicilar.Items.Count; i++) {
while(lstKullanicilar.Items[i].Count > 1){
lstKullanicilar.Items[i].SubItems.RemoveAt(1);
}
}
The problem with your code is probably that you have a variable amount of items in the SubItems-collection. WIth the code you showed, you must at least have 6 items in the subitems-collection, for not getting an arugment exception.