Reputation: 2499
I make a listbox and it works perfectly, I also made a search function, but I want to hide the items in the listbox and show them only when searched through index. here is my code for adding items
private void Savebtn_Click(object sender, EventArgs e)
{
addTolist(gatherItem());
refreshView();
}
private void addTolist(Person p)
{
Person.listperson.Add(p);
}
private void refreshView()
{
listBox1.Items.Add(getItem());
}
private String getItem()
{
String result = null;
foreach (Person p in Person.listperson)
{
result = p.lastname;
}
return result;
}
and this is my code for search
private void button1_Click(object sender, EventArgs e)
{
int index = listBox1.FindString(textBox6.Text);
if (0 <= index)
{
listBox1.SelectedIndex = index;
}
}
Is there a way for this? thanks :)
Upvotes: 1
Views: 13010
Reputation: 21
The easiest way to do this, is to create a List<string>
item that will store removed items (or items that do not match the search-phrase given in textbox1
), an int
variable that will store how many characters there were the last time the TextChanged
event was triggered, and then create a function for your listbox element that activates when the phrase in a textbox is updated:
private void textbox1_TextChanged(object sender, EventArgs e) {}
in this function, there are two things that could happen:
if a character was added to textbox1
:
listbox
.textbox1
if a character was removed from textbox1
:
List<string>
variable you made to store the values you removed from your listbox
textbox1
(check for duplicates though)Here's the code I wrote to use as reference:
private List<string> temporarilyRemovedSongs = new List<string>();
private int previousTextLength = 0;
private void filter_songs_textbox_TextChanged(object sender, EventArgs e)
{
List<string> toRemove = new List<string>();
string text = Tools.Strip(this.filter_songs_textbox.Text.ToLower());
if (text.Length > this.previousTextLength)
{
// a char was added, remove songs that do not start with the search-phrase
foreach (string song in this.songs_list.Items)
{
if (!song.ToLower().Contains(text))
{
this.temporarilyRemovedSongs.Add(song);
toRemove.Add(song);
}
}
foreach (string song in toRemove)
{
this.songs_list.Items.Remove(song);
}
}
else
{
// a char was removed; look through removed songs to add back
foreach (string song in this.temporarilyRemovedSongs)
{
if (song.Contains(text) && !this.songs_list.Items.Contains(song))
this.songs_list.Items.Add(song);
}
}
previousTextLength = text.Length;
}
Upvotes: 0
Reputation: 143
You can cover a dummy ListBox on your origin one, and set origin one invisible. Then you can archive the same effect by writing codes like
class DummyItem {
public string text;
public int index;
public override string ToString() {
return text;
}
}
public void build_dummy() {
listbox_dummy.Items.Clear();
for (int i = 0; i < listbox_origin.Items.Count; i++) {
// replace with your own judgement
if (! should_hide(listbox_origin.Items[i])) {
DummyItem item = new DummyItem();
item.text = listbox_origin.Items[i].ToString();
item.index = i;
listbox_dummy.Items.Add(item);
}
}
}
private void listbox_dummy_SelectedIndexChanged(object sender, EventArgs e) {
var item = (DummyItem) listbox_dummy.SelectedItem;
var index = item.index;
listbox_origin.SelectedIndex = index;
}
Upvotes: 0
Reputation: 3258
There is no easy way to do this with winforms. It a lot easier with WPF. With winforms you will have to remove
the items. You could technically use databinding, but its not recommended at all, because listbox is supposed to used directly from your code according the MSDN documentation.
On second thought, you could overdraw the listbox and set the item you want to hide to transparent or something, buts its not easy. You may want to consider storing all your values in an array and then loop through array and only adding the elements you want. Or switch to WPF.
Hope this helps.
Upvotes: 2