所以我正在使用基于文本框的筛选器,使用c#在winforms中的Checked List Box中检查一堆项目。
到目前为止,我有以下代码:
List<string> liscollection = new List<string>();
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text) == false)
{
checkedListBox1.Items.Clear();
foreach (string str in liscollection)
{
if (str.Contains(textBox1.Text, StringComparison.OrdinalIgnoreCase))
{
checkedListBox1.Items.Add(str);
}
}
}
else if (textBox1.Text == "")
{
checkedListBox1.Items.Clear();
foreach (string str in liscollection)
{
checkedListBox1.Items.Add(str);
}
}
}
当我在TextBox1中输入文本时,一切正常,所有不包含输入文本的项目都消失了。
问题涉及到每个项目的检查状态。每次checkedListBox1.Items.Clear();被调用时,检查状态也将被清除。
有没有一种方法可以使过滤器保持工作状态,但又不能清除项目的已检查状态?
我已经寻找了一段时间,对此一无所获,我是一个初学者,无法独自提出解决方案。
非常感谢您抽出宝贵的时间!
请问我的英语不是我的母语:)
参考方案
CheckListBox.Items
的类型为ObjectCollection
,这意味着它将接受任何object
,而不仅仅是string
。默认情况下,CheckedListBox
将显示ToString
的结果作为项目的文本。
这意味着您可以编写一个class
来表示存储在CheckedListBox
中的项目,这些项目跟踪其自己的CheckedState
属性,然后覆盖ToString
方法,以便显示所需的文本。
// CheckedListBoxItem.cs
public class CheckedListBoxItem
{
/// <summary>
/// The item's text - what will be displayed in the CheckedListBox.
/// </summary>
public string Text { get; set; }
/// <summary>
/// The item's check state.
/// </summary>
public CheckState CheckState { get; set; } = CheckState.Unchecked;
/// <summary>
/// Whether the item is checked or not.
/// </summary>
public bool Checked
{
get
{
return (CheckState == CheckState.Checked || CheckState == CheckState.Indeterminate);
}
set
{
if (value)
{
CheckState = CheckState.Checked;
}
else
{
CheckState = CheckState.Unchecked;
}
}
}
public bool Contains(string str, StringComparison comparison)
{
return Text.IndexOf(str, comparison) >= 0;
}
public override string ToString()
{
return Text;
}
}
CheckedListBoxItem.Checked
的行为基于将CheckedListBox.GetItemChecked
视为已选中的CheckState.Interetminate
和将CheckedListBox.SetItemChecked
视为true
并将CheckState.Checked
视为false
的CheckState.Unchecked
。
然后,在您的Form
中,将lstcollection
的类型更改为List<CheckedListBoxItem>
,并将每个项目的Text
属性设置为您现在拥有的字符串。
CheckedListBox
没有任何方式绑定每个项目的CheckState
,因此您必须自己进行管理。幸运的是,有一个CheckedListBox.ItemChecked
事件将在项目的选中状态更改时触发。因此,您可以使用以下功能处理事件:
private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
// Since each item in the CheckedListBox is of type CheckedListBoxItem, we can
// just cast to that type...
CheckedListBoxItem item = checkedListBox1.Items[e.Index] as CheckedListBoxItem;
// Then set the checked state to the new value.
item.CheckState = e.NewValue;
}
过滤器功能在很大程度上保持不变,但是当您将项目添加到CheckedListBox
时,还必须通过CheckedState
。
private List<CheckedListBoxItem> liscollection;
private void textBox1_TextChanged(object sender, EventArgs e)
{
checkedListBox1.Items.Clear();
if (string.IsNullOrEmpty(textBox1.Text) == false)
{
foreach (var item in liscollection)
{
if (item.Contains(textBox1.Text, StringComparison.OrdinalIgnoreCase))
{
checkedListBox1.Items.Add(item, item.CheckState);
}
}
}
else
{
foreach (var item in liscollection)
{
checkedListBox1.Items.Add(item, item.CheckState);
}
}
}
编辑
对于这种情况,我不会在设计时将项目添加到checkedListBox1
。我会在运行时将它们添加到liscollection
,然后将liscollection
添加到checkedListBox1.Items
。
public class YourForm : Form
{
public YourForm()
{
InitializeComponent();
// You would add one item to liscollection for each item that you have in the checkedListBox1's designer and set the Text to whatever the item is now...
liscollection = new List<CheckedListBoxItem>
{
new CheckedListBoxItem { Text = "The" },
new CheckedListBoxItem { Text = "needs" },
new CheckedListBoxItem { Text = "of" },
new CheckedListBoxItem { Text = "the" },
new CheckedListBoxItem { Text = "many" },
new CheckedListBoxItem { Text = "outweigh" },
new CheckedListBoxItem { Text = "the" },
new CheckedListBoxItem { Text = "needs" },
new CheckedListBoxItem { Text = "of" },
new CheckedListBoxItem { Text = "the" },
new CheckedListBoxItem { Text = "few" },
};
checkedListBox1.Items.AddRange(liscollection.ToArray());
}
}
如果您真的希望从设计器中填充checkedListBox1
,也可以这样做。您只需在填充checkedListBox1.Items.Clear()
之后且在调用liscollection
之前调用checkedListBox1.Items.AddRange(...)
public class YourForm : Form
{
public YourForm()
{
InitializeComponent();
liscollection = new List<CheckedListBoxItem>();
foreach(string str in checkedListBox1.Items)
{
liscollection.Add(new CheckedListBoxItem { Text = str });
}
checkedListBox1.Items.Clear();
checkedListBox1.Items.AddRange(liscollection.ToArray());
}
}
重要行是checkedListBox1.Items.AddRange(liscollection.ToArray())
。您希望Items
是CheckedListBoxItem
的实例,这样在ItemCheck
事件中,您可以将项目强制转换为CheckedListBoxItem
的实例。通过从设计器填充checkedListBox1
,您仅用string
填充了它,因此,当您尝试在CheckedListBoxItem
事件中强制转换为ItemCheck
时,它将失败。这就是为什么要获取该NullReferenceException
的原因。
我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
如何使用%s在python中使用Selenium变量构建xpath表达式 - python我正在尝试使用硒根据调用时传递给函数的变量来定位和选择某个元素。我以为,有了一个好的ol,这将足够简单:show = browser.find_element_by_xpath("//*[contains(text(), '%s')]" % eventName) 但是,我收到错误:selenium.common.exc…
使用Json.NET反序列化复杂对象 - c#我需要反序列化从grogle maps api返回的json:{ "destination_addresses": [ "Via Medaglie D'Oro, 10, 47121 Forlì FC, Italia", "Via Torino, 20123 Milano, Italia",…
Mongo汇总 - javascript我的收藏中有以下文件{ "_id": ObjectId("54490b8104f7142f22ecc97f"), "title": "Sample1", "slug": "samplenews", "cat": …
如何在Wiremock中为JUNIT匹配精确的json - java我正在使用Wiremock在Spring启动应用程序中模拟Junit的REST服务。我的问题是,我无法匹配多个匹配模式。 Junit.javaStringValuePattern pattern = WireMock.matching(".*"); givenThat(post(urlEqualTo("/softwares…