如何使用 TextBox 过滤 DataGridView
How to filter DataGridView using TextBox
我还没有太多经验。我正在尝试过滤包含输入文本的行。
为了..
我使用 MailKit 接收传入的消息并将来自它们的数据放入 Grid
public void ShowMessages(ImapClient client)
{
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
var query = SearchQuery.All;
var uids = inbox.Search(query);
var items = inbox.Fetch(uids, MessageSummaryItems.Full | MessageSummaryItems.BodyStructure).Reverse();
foreach (var item in items)
{
...
dataGridMessages.Rows.Add(read, item.Envelope.Subject, item.Envelope.From, item.Envelope.Date, attach, item.Size, false, item.UniqueId);
}
}
然后我尝试过滤行
private void searchTxb_TextChanged(object sender, EventArgs e)
{
BindingSource bs = new BindingSource();
bs.DataSource = dataGridMessages.DataSource;
bs.Filter = string.Format("Subject LIKE '%{0}%'", searchTxb.Text);
dataGridMessages.DataSource = bs;
}
但是输入文本后,网格是空的,什么也找不到。
请告诉我我做错了什么?
您的问题是由于您在网格中一次填充一行而直接添加一行引起的。这样,DataSource 属性 没有设置任何值,如果你想过滤你需要逐行循环并删除不需要的行。
或者,您可以使用 BindingList<T>
,其中 T 是您在代码中定义的自定义 class,仅包含您希望在网格中显示的属性。定义此 class 后,您可以创建实例以添加到 BindingList 构造函数中使用的列表中
所以假设有一个像这样的class
private class MailItem
{
public string Subject {get;set;}
public string From {get;set;}
public DateTime DateSent {get;set;}
}
还有一个全局变量在你的 type
表单中
List<MailItem> rows = new List<MailItem>();
为简单起见,我只添加了一些属性,但您可以轻松添加其他属性。
现在当你需要填充网格时使用这个
...
rows.Clear();
var items = inbox.Fetch(uids, MessageSummaryItems.Full | MessageSummaryItems.BodyStructure).Reverse()
foreach(var item in items)
{
rows.Add(new MailItem {
Subject = item.Envelope.Subject,
From = item.Envelope.From,
DateSent = item.Envelope.Date
};
}
现在您可以创建 BindingList 并将其设置为网格的数据源
BindingList<MailItem> bs = new BindingList<MailItem>(rows);
dataGridMessages.DataSource = bs;
最后一步是过滤代码。在这里你需要提取你想要使用的行并应用过滤器
BindingList<MailItem> currentFilter = new BindingList<MailItem>(rows);
dataGridMessages.DataSource = currentFilter.Where(x => x.Subject.Contains(searchTxb.Text)).ToList();
请注意,您需要保留通过调用 Fetch 检索到的原始行集,以便您可以在用户更改文本框内容时应用不同的过滤器。因此,MailItem 列表应该为您的表单保持全局
或者您可以再次调用 Fetch,但即使只检索 100 个元素,这种方法似乎也很慢。更好的模型(恕我直言)是实现一个按钮并在单击该按钮时调用过滤器。
(BindingList 需要 使用 System.ComponentModel)
我还没有太多经验。我正在尝试过滤包含输入文本的行。 为了.. 我使用 MailKit 接收传入的消息并将来自它们的数据放入 Grid
public void ShowMessages(ImapClient client)
{
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
var query = SearchQuery.All;
var uids = inbox.Search(query);
var items = inbox.Fetch(uids, MessageSummaryItems.Full | MessageSummaryItems.BodyStructure).Reverse();
foreach (var item in items)
{
...
dataGridMessages.Rows.Add(read, item.Envelope.Subject, item.Envelope.From, item.Envelope.Date, attach, item.Size, false, item.UniqueId);
}
}
然后我尝试过滤行
private void searchTxb_TextChanged(object sender, EventArgs e)
{
BindingSource bs = new BindingSource();
bs.DataSource = dataGridMessages.DataSource;
bs.Filter = string.Format("Subject LIKE '%{0}%'", searchTxb.Text);
dataGridMessages.DataSource = bs;
}
但是输入文本后,网格是空的,什么也找不到。 请告诉我我做错了什么?
您的问题是由于您在网格中一次填充一行而直接添加一行引起的。这样,DataSource 属性 没有设置任何值,如果你想过滤你需要逐行循环并删除不需要的行。
或者,您可以使用 BindingList<T>
,其中 T 是您在代码中定义的自定义 class,仅包含您希望在网格中显示的属性。定义此 class 后,您可以创建实例以添加到 BindingList 构造函数中使用的列表中
所以假设有一个像这样的class
private class MailItem
{
public string Subject {get;set;}
public string From {get;set;}
public DateTime DateSent {get;set;}
}
还有一个全局变量在你的 type
表单中List<MailItem> rows = new List<MailItem>();
为简单起见,我只添加了一些属性,但您可以轻松添加其他属性。
现在当你需要填充网格时使用这个
...
rows.Clear();
var items = inbox.Fetch(uids, MessageSummaryItems.Full | MessageSummaryItems.BodyStructure).Reverse()
foreach(var item in items)
{
rows.Add(new MailItem {
Subject = item.Envelope.Subject,
From = item.Envelope.From,
DateSent = item.Envelope.Date
};
}
现在您可以创建 BindingList 并将其设置为网格的数据源
BindingList<MailItem> bs = new BindingList<MailItem>(rows);
dataGridMessages.DataSource = bs;
最后一步是过滤代码。在这里你需要提取你想要使用的行并应用过滤器
BindingList<MailItem> currentFilter = new BindingList<MailItem>(rows);
dataGridMessages.DataSource = currentFilter.Where(x => x.Subject.Contains(searchTxb.Text)).ToList();
请注意,您需要保留通过调用 Fetch 检索到的原始行集,以便您可以在用户更改文本框内容时应用不同的过滤器。因此,MailItem 列表应该为您的表单保持全局
或者您可以再次调用 Fetch,但即使只检索 100 个元素,这种方法似乎也很慢。更好的模型(恕我直言)是实现一个按钮并在单击该按钮时调用过滤器。
(BindingList 需要 使用 System.ComponentModel)