C# 使用 TextBox 实时过滤 ListBox
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9983720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filter ListBox with TextBox in realtime
提问by observ
I am trying to filter an listbox with text from a textbox, realTime.
我正在尝试从文本框中实时过滤带有文本的列表框。
Here is the code:
这是代码:
private void SrchBox_TextChanged_1(object sender, EventArgs e)
{
var registrationsList = registrationListBox.Items.Cast<String>().ToList();
registrationListBox.BeginUpdate();
registrationListBox.Items.Clear();
foreach (string str in registrationsList)
{
if (str.Contains(SrchBox.Text))
{
registrationListBox.Items.Add(str);
}
}
registrationListBox.EndUpdate();
}
Here are the issues:
以下是问题:
When I run the program i get this error:
Object reference not set to an instance of an objectIf I hit backspace, my initial list is not shown anymore. This is because my actual list of items is now reduced, but how can I achieve this?
当我运行程序时,我收到此错误:
Object reference not set to an instance of an object如果我按退格键,则不再显示我的初始列表。这是因为我的实际项目清单现在减少了,但我怎样才能做到这一点?
Can you point me in the right direction?
你能为我指出正确的方向吗?
采纳答案by Tigran
It's hard to deduct just from the code, but I presumeyour filtering problem born from the different aspects:
仅从代码中很难推断出,但我认为您的过滤问题来自不同方面:
a) You need a Modelof the data shown on ListBox. You need a colleciton of "Items" which you hold somewhere (Dictionary, DataBase, XML, BinaryFile, Collection), some kind of Storein short.
a) 您需要Model中显示的数据ListBox。您需要在某处 ( Dictionary, DataBase, XML, BinaryFile, Collection)保存的“物品”集合,简称为某种Store。
To show the data on UI you alwayspick the data from that Store, filter it and put it on UI.
要在 UI 上显示数据,您总是从该Store 中选择数据,对其进行过滤并将其放在 UI 上。
b) After the first point your filtering code can look like this (a pseudocode)
b) 在第一点之后,您的过滤代码可能如下所示(伪代码)
var registrationsList = DataStore.ToList(); //return original data from Store
registrationListBox.BeginUpdate();
registrationListBox.Items.Clear();
if(!string.IsNullOrEmpty(SrchBox.Text))
{
foreach (string str in registrationsList)
{
if (str.Contains(SrchBox.Text))
{
registrationListBox.Items.Add(str);
}
}
}
else
registrationListBox.Items.AddRange(registrationsList); //there is no any filter string, so add all data we have in Store
registrationListBox.EndUpdate();
Hope this helps.
希望这可以帮助。
回答by James Johnson
Something like this might work for you:
像这样的事情可能对你有用:
var itemList = registrationListBox.Items.Cast<string>().ToList();
if (itemList.Count > 0)
{
//clear the items from the list
registrationListBox.Items.Clear();
//filter the items and add them to the list
registrationListBox.Items.AddRange(
itemList.Where(i => i.Contains(SrchBox.Text)).ToArray());
}
回答by observ
Yes that was the answer to filtering. (modified a bit). I had the info in a text file. This is what worked for me
是的,这就是过滤的答案。(稍作修改)。我有一个文本文件中的信息。这对我有用
FileInfo registrationsText = new FileInfo(@"name_temp.txt");
StreamReader registrationsSR = registrationsText.OpenText();
var registrationsList = registrationListBox.Items.Cast<string>().ToList();
registrationListBox.BeginUpdate();
registrationListBox.Items.Clear();
if (!string.IsNullOrEmpty(SrchBox.Text))
{
foreach (string str in registrationsList)
{
if (str.Contains(SrchBox.Text))
{
registrationListBox.Items.Add(str);
}
}
}
else
while (!registrationsSR.EndOfStream)
{
registrationListBox.Items.Add(registrationsSR.ReadLine());
}
registrationListBox.EndUpdate();
It seems that the error:
似乎是错误:
Object reference not set to an instance of an object
你调用的对象是空的
is from somewhere else in my code, can't put my finger on it.
来自我代码中的其他地方,我无法理解它。
回答by KC Drez
If able, store everything in a dictionary and just populate it from there.
如果可以,将所有内容存储在字典中,然后从那里填充它。
public partial class myForm : Form
{
private Dictionary<string, string> myDictionary = new Dictionary<string, string>();
//constructor. populates the items. Assumes there is a listbox (myListbox) and a textbox (myTextbox), named respectively
public myForm()
{
InitializeComponent();
myDictionary.Add("key1", "item1");
myDictionary.Add("key2", "My Item");
myDictionary.Add("key3", "A Thing");
//populate the listbox with everything in the dictionary
foreach (string s in myDictionary.Values)
myListbox.Add(s);
}
//make sure to connect this to the textbox change event
private void myTextBox_TextChanged(object sender, EventArgs e)
{
myListbox.BeginUpdate();
myListbox.Items.Clear();
foreach (string s in myDictionary.Values)
{
if (s.Contains(myListbox.Text))
myListbox.Items.Add(s);
}
myListbox.EndUpdate();
}
}
回答by Anonimous
I would do it like this:
我会这样做:
private List<string> registrationsList;
private void SrchBox_TextChanged_1(object sender, EventArgs e)
{
registrationListBox.BeginUpdate();
registrationListBox.Items.Clear();
var filteredList = registrationList.Where(rl => rl.Contains(SrchBox.Text))
registrationListBox.Items.AddRange();
registrationListBox.EndUpdate();
}
Just remember to populate registrationsList the first time you fill your listbox.
请记住在您第一次填充列表框时填充注册列表。
Hope this helps.
希望这可以帮助。
回答by Giorgio C.
it was a very hard issue for me, but I found a workaround (not so simple) that works fine for me.
这对我来说是一个非常困难的问题,但我找到了一个对我来说很好的解决方法(不是那么简单)。
on aspx page:
在aspx页面上:
<input id="ss" type="text" oninput="writeFilterValue()"/>
<asp:HiddenField ID="hf1" runat="server" Value="" ClientIDMode="Static" />
I need HTML input type because of "oninput" function, that is not availiable on classic asp.net controls. The writeFilterValue() function causes a postback that filters values of a given ListBox (in code-behind).
由于“oninput”功能,我需要 HTML 输入类型,这在经典的 asp.net 控件上不可用。writeFilterValue() 函数导致过滤给定 ListBox(在代码隐藏中)的值的回发。
I've defined this two javascript function:
我已经定义了这两个 javascript 函数:
<script type="text/javascript">
function writeFilterValue() {
var bla = document.getElementById("ss").value;
$("#hf1").val(bla)
__doPostBack();
}
function setTboxValue(s) {
document.getElementById('ss').value = s;
document.getElementById('ss').focus();
}
</script>
You can now use postback on code-behind to capture hf1 value, every time some single Character is typed on inputbox. On code-behind:
您现在可以在代码隐藏上使用回发来捕获 hf1 值,每次在输入框上键入单个字符时。关于代码隐藏:
If IsPostBack Then
FiltraLbox(hf1.Value)
End If
The function FiltraLbox(hf1.Value) changes datasource of Listbox, and rebind it:
函数 FiltraLbox(hf1.Value) 改变 Listbox 的数据源,并重新绑定它:
Public Sub FiltraLbox(ByVal hf As String)
If hf <> "" Then
' change datasource here, that depends on hf value,
ListBox1.DataBind()
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "text", setTboxValue('" + hf + "');", True)
End If
End Sub
At the end I call the function setTboxValue(), that rewrites the input text value lost on postback, and puts the focus on it.
最后,我调用函数 setTboxValue(),它重写回发时丢失的输入文本值,并将重点放在它上面。
Enjoy it.
好好享受。

