Reputation: 1217
My program generates ListView full of information. I type into a text box a name that might match one of the item names in the ListView. I want this typed name to weed out the names from the ListView that don't match.
For example, if I type in "abc", names like "uvw" and "xyz" wouldn't show up anymore, but "abc" and "abcde" would still show up in the list view.
The end goal is to be able to check the checkboxes next to the names I want, and search for more names, eventually selecting several, without resetting the checkboxes.
Right now I click a button and the ListView is populated:
private void button1_Click(object sender, EventArgs e)
{
List<string> myList = getList();
foreach(string s in myList)
{
listView1.Items.Add(s);
}
}
getList()
just returns a List<string>
of all the names I want.
I can't figure out how to make the ListView update in real time when I type in my text box. I'm able to update it with a button click via repopulating the ListView based on looping through the List, and checking each name, but that's not what I want. It also doesn't retain checked check boxes, as it's a newly generated list each time.
I read about a "text change listener", but I'm not sure that's what I should be using here...
Upvotes: 3
Views: 7709
Reputation: 1538
With filtering you need some way of remembering which ListViewItems are selected, so instead of inserting all your ListViewItems into your listview you want to instantiate them in a master list. Then attach a TextChanged event handler to your text box and when the text changes you display the items.
List<ListViewItem> masterlist;
public Form1()
{
InitializeComponent();
masterlist = new List<ListViewItem>();
}
private void button1_Click(object sender, EventArgs e)
{
// Populate the masterlist
masterlist.Clear();
foreach(string s in getList())
{
masterlist.Items.Add(new ListViewItem(s));
}
// Display the items in the listview
DisplayItems();
}
private void DisplayItems()
{
listView1.Items.Clear();
// This filters and adds your filtered items to listView1
foreach(ListViewItem item in masterlist.Where(lvi => lvi.Text.ToLower().Contains(textBox1.Text.ToLower().Trim())))
{
listView1.Items.Add(item);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
// Re-display the items when the filter changes
DisplayItems();
}
As you're dealing directly with ListViewItems in your masterlist
they will retain their checked state when swapped in and out of listView1
.
I have assumed that your filter textbox is called textBox1
.
Upvotes: 7
Reputation: 2728
If you want to go for a full C# solution (rather than using any Javascript), as much as it pains me, I would suggest using an UpdatePanel.
Put your ListBox
inside they the <ContentTemplate>
section of the <UpdatePanel>
then add an <asp:AsyncPostBackTrigger>
with the ControlID
set to that of your textbox. Make sure that the UpdateMode
property of the UpdatePanel
is set to "Conditional".
On your TextBox
you will also have to set the AutoPostBack
property to true
. On the TextBox
itself you will have to create a TextChanged
event handler, then in your code behind (.cs
file) you will have the logic for your TextChanged handler which will filter the list then set the new value for your ListBox
.
UpdatePanel
s are ok for simply scenarios, but you can very easily get yourself into trouble by mis-using them.
Upvotes: -1