在 CheckedListBox C# 中搜索项目
Search in for items in CheckedListBox C#
我有一个 CheckedListBox 和一个文本框。这里的目标是制作一个可搜索的 CheckedListBox。当我在 TextBox 中键入内容时,我必须过滤 CheckedListBox 中的项目。
我已经编写了下面的代码来这样做,但是每次我输入文本时,CheckedListBox 项目都会被清除,并且会出现新的过滤项目列表。此代码的问题是过滤工作正常,但每次都会重置选中的项目。
public partial class Form1 : Form
{
string[] elArray = {"Not Applicable" , "Aberdeen - Delivered" , "Belfast - Delivered" , "Birmingham - Delivered" , "Bournemouth - Delivered" , "Bradford - Delivered" , "Bristol - Delivered" , "Cambridge - Delivered" , "Canterbury - Delivered" , "OTHERS TO DE ADDED ..."};
public Form1()
{
InitializeComponent();
foreach (string elData in elArray)
{
resultBoxList.Items.Add(elData);
}
}
private void searchBox_TextChanged(object sender, EventArgs e)
{
resultBoxList.Items.Clear();
string[] resultArray = { };
foreach (string res in elArray)
{
if (res.Contains(searchBox.Text))
{
resultBoxList.Items.Add(res);
}
}
foreach (string resData in resultArray)
{
resultBoxList.Items.Add(resData);
}
}
}
您有两个问题需要解决,至:
- 应用过滤器并保留列表项。
- 保留项目的选中状态。
您可以使用 DataTable as the data source of the list items and their checked states, and bind it's default DataView to the CheckedListBox.DataSource 属性.
注意:CheckedListBox控件的DataSource
、DisplayMember
和ValueMember
属性是隐藏的。它们不会出现在属性 Window 中,也不会出现在 IntelliSense 中。
首先,创建 DataTable,添加项目,并填充控件。
public Form1()
{
InitializeComponent();
var elArray = new[]
{
"Not Applicable",
"Aberdeen - Delivered",
"Belfast - Delivered",
"Birmingham - Delivered",
"Bournemouth - Delivered",
"Bradford - Delivered",
"Bristol - Delivered",
"Cambridge - Delivered",
"Canterbury - Delivered",
"OTHERS TO DE ADDED ..."
};
var dt = new DataTable();
dt.Columns.Add("Item", typeof(string));
dt.Columns.Add("Checked", typeof(bool));
foreach (var item in elArray) dt.Rows.Add(item, false);
dt.AcceptChanges();
resultBoxList.DataSource = dt.DefaultView;
resultBoxList.DisplayMember = "Item";
resultBoxList.ValueMember = "Item";
// If not already done by the designer...
resultBoxList.ItemCheck += resultBoxList_ItemCheck;
}
其次,处理ItemCheck事件以更新数据源中的选中状态。
private void resultBoxList_ItemCheck(object sender, ItemCheckEventArgs e)
{
var dv = resultBoxList.DataSource as DataView;
var drv = dv[e.Index];
drv["Checked"] = e.NewValue == CheckState.Checked ? true : false;
}
最后,在TextChanged
事件中,解决上述问题:
- 设置DataView.RowFilter to apply/remove the filter. In your case, you need to use the LIKE运算符。有关更多模式和详细信息,请参阅参考 link。
- 从数据源恢复勾选状态。
private void searchBox_TextChanged(object sender, EventArgs e)
{
var dv = resultBoxList.DataSource as DataView;
var filter = searchBox.Text.Trim().Length > 0
? $"Item LIKE '{searchBox.Text}*'"
: null;
dv.RowFilter = filter;
for (var i = 0; i < resultBoxList.Items.Count; i++)
{
var drv = resultBoxList.Items[i] as DataRowView;
var chk = Convert.ToBoolean(drv["Checked"]);
resultBoxList.SetItemChecked(i, chk);
}
}
我有一个 CheckedListBox 和一个文本框。这里的目标是制作一个可搜索的 CheckedListBox。当我在 TextBox 中键入内容时,我必须过滤 CheckedListBox 中的项目。 我已经编写了下面的代码来这样做,但是每次我输入文本时,CheckedListBox 项目都会被清除,并且会出现新的过滤项目列表。此代码的问题是过滤工作正常,但每次都会重置选中的项目。
public partial class Form1 : Form
{
string[] elArray = {"Not Applicable" , "Aberdeen - Delivered" , "Belfast - Delivered" , "Birmingham - Delivered" , "Bournemouth - Delivered" , "Bradford - Delivered" , "Bristol - Delivered" , "Cambridge - Delivered" , "Canterbury - Delivered" , "OTHERS TO DE ADDED ..."};
public Form1()
{
InitializeComponent();
foreach (string elData in elArray)
{
resultBoxList.Items.Add(elData);
}
}
private void searchBox_TextChanged(object sender, EventArgs e)
{
resultBoxList.Items.Clear();
string[] resultArray = { };
foreach (string res in elArray)
{
if (res.Contains(searchBox.Text))
{
resultBoxList.Items.Add(res);
}
}
foreach (string resData in resultArray)
{
resultBoxList.Items.Add(resData);
}
}
}
您有两个问题需要解决,至:
- 应用过滤器并保留列表项。
- 保留项目的选中状态。
您可以使用 DataTable as the data source of the list items and their checked states, and bind it's default DataView to the CheckedListBox.DataSource 属性.
注意:CheckedListBox控件的DataSource
、DisplayMember
和ValueMember
属性是隐藏的。它们不会出现在属性 Window 中,也不会出现在 IntelliSense 中。
首先,创建 DataTable,添加项目,并填充控件。
public Form1()
{
InitializeComponent();
var elArray = new[]
{
"Not Applicable",
"Aberdeen - Delivered",
"Belfast - Delivered",
"Birmingham - Delivered",
"Bournemouth - Delivered",
"Bradford - Delivered",
"Bristol - Delivered",
"Cambridge - Delivered",
"Canterbury - Delivered",
"OTHERS TO DE ADDED ..."
};
var dt = new DataTable();
dt.Columns.Add("Item", typeof(string));
dt.Columns.Add("Checked", typeof(bool));
foreach (var item in elArray) dt.Rows.Add(item, false);
dt.AcceptChanges();
resultBoxList.DataSource = dt.DefaultView;
resultBoxList.DisplayMember = "Item";
resultBoxList.ValueMember = "Item";
// If not already done by the designer...
resultBoxList.ItemCheck += resultBoxList_ItemCheck;
}
其次,处理ItemCheck事件以更新数据源中的选中状态。
private void resultBoxList_ItemCheck(object sender, ItemCheckEventArgs e)
{
var dv = resultBoxList.DataSource as DataView;
var drv = dv[e.Index];
drv["Checked"] = e.NewValue == CheckState.Checked ? true : false;
}
最后,在TextChanged
事件中,解决上述问题:
- 设置DataView.RowFilter to apply/remove the filter. In your case, you need to use the LIKE运算符。有关更多模式和详细信息,请参阅参考 link。
- 从数据源恢复勾选状态。
private void searchBox_TextChanged(object sender, EventArgs e)
{
var dv = resultBoxList.DataSource as DataView;
var filter = searchBox.Text.Trim().Length > 0
? $"Item LIKE '{searchBox.Text}*'"
: null;
dv.RowFilter = filter;
for (var i = 0; i < resultBoxList.Items.Count; i++)
{
var drv = resultBoxList.Items[i] as DataRowView;
var chk = Convert.ToBoolean(drv["Checked"]);
resultBoxList.SetItemChecked(i, chk);
}
}