如何使用 TextBox 过滤 DataGridView

Posted

技术标签:

【中文标题】如何使用 TextBox 过滤 DataGridView【英文标题】:How to filter DataGridView using TextBox 【发布时间】:2021-12-07 10:27:53 【问题描述】:

我还没有太多经验。我正在尝试过滤包含输入文本的行。 为了.. 我使用 MailKit 接收传入的消息并将来自它们的数据放入网格中

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,所以我认为您在该 DataSource 属性中没有任何要过滤的内容。 ***.com/questions/70142533/… @Steve 我需要以不同的方式填充网格吗? @senthilkumar2185 它会给我什么? 我将创建一个私有类,其中包含您需要在网格中显示的属性。使用 linq 创建该类的实例并创建一个列表。最后创建一个 BindingSource,将其数据源设置为列表并将所有内容传递给网格的数据源。那么你的过滤器应该可以工作了 【参考方案1】:

您的问题是由于您一次填充网格一行而直接添加一行。这样,DataSource 属性不会设置为任何内容,如果要过滤,则需要逐一循环遍历行并删除不需要的行。

您也可以使用BindingList<T>,其中 T 是您在代码中定义的自定义类,仅包含您希望在网格中显示的属性。定义此类后,您可以创建实例以添加到 BindingList 构造函数中使用的 List

所以假设有这样的课程

private class MailItem

    public string Subject get;set;
    public string From get;set;
    public DateTime DateSent get;set;

以及类型形式中的全局变量

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 并将其设置为网格的 DataSource

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

【讨论】:

以上是关于如何使用 TextBox 过滤 DataGridView的主要内容,如果未能解决你的问题,请参考以下文章

通过 TextBox(C#、WinForms)过滤空 DataGridView

使用 TextBox 和 DatePicker 元素过滤 WPF DataGrid 行

从后面的代码中过滤 TextBox 的 KeyPress 事件上的 GridView

正则表达式无法过滤 WinForms 中的 TextBox 字符

asp.net中如何判断input#textbox内容为空

留言板过滤 脏字 问题 求 一个能用的 正则表达式匹配并替换. 如过滤 TextBox1 里面的文本