如何使用DataTable.DefaultView.RowFilter过滤项目

问题描述 投票:0回答:1

我的项目中有

listbox
,它绑定到
datasource
。我希望能够仅过滤与我在附加
textbox
控件中输入的文本匹配的项目。我知道我可能会在我的旧
vb.net 项目
中使用以下 DefaultView.RowFilter 属性,如下所示。然而,当我尝试在最近的 visual studio C# 项目 中执行相同操作时,似乎
DefaultView
不再被识别。如果这已停用或有任何其他方式我可以如何过滤项目,有什么想法吗?

listbox1.DataSource.DefaultView.RowFilter = "[Nummer] like '%" & lbSearchProd.Text.Trim()

编辑@dr.null

我添加了以下行,但我收到以下错误。请注意,数据源包含项目。

(cbClient.DataSource as DataTable).DefaultView.RowFilter = "[Value] like '%" + txtFilterClient.Text.Trim() + "%'";

这就是我绑定控件的方式:

public void LoadDataToClients(IEnumerable<IdValueReadModel> clients)
{
    cbClient.DataSource = clients.ToList();
    cbClient.DisplayMember = "Value";
    cbClient.ValueMember = "Id";
}

数据在那里:

c# vb.net winforms datatable rowfilter
1个回答
3
投票

澄清对您上述问题的评论。

首先

listbox1.DataSource.DefaultView.RowFilter = "[Nummer] like '%" & lbSearchProd.Text.Trim()

此行适用于您的旧 vb.net 项目,因为您拥有

Option Strict Off
,它允许隐式缩小转换、后期绑定和隐式键入,从而产生
object
类型。如果您想编写良好的 vb.net 代码并通过这样做避免可能的错误和错误,则不应允许上述情况。在 C# 中,你没有这个选项。您需要将
object
转换为分配的对象实例的类型才能访问它。

其次,您的数据源是

List<T>
而不是
DataTable
。它们是两种不同的东西,你不能将可以为一种东西编写的东西应用到另一种东西上。您需要
Linq
来过滤
List<T>

一些建议的解决方案。


数据表
从您的数据访问中获得

DataTable
。比如:

// SqlClient example...
private DataTable GetDataTable()
{
    var dt = new DataTable();

    using (var con = new SqlConnection("...."))
    using (var cmd = new SqlCommand("Select...", con))
    using (var da = new SqlDataAdapter(cmd))
    {
        con.Open();
        da.Fill(dt);
    }

    return dt;
}

绑定:

private void LoadClient()
{
    cbClient.DisplayMember = "Value";
    cbClient.ValueMember = "Id";
    cbClient.DataSource = GetDataTable();
}

手柄

TextBox.TextChanged
进行过滤或移除过滤器:

private void txtFilterClient_TextChanged(object sender, EventArgs e)
{
    if (cbClient.DataSource is DataTable dt)
    {
        var str = txtFilterClient.Text.Trim();

        dt.DefaultView.RowFilter = string.IsNullOrEmpty(str)
            ? null
            : $"Value LIKE '%{str}%'";
    }
}


绑定源
与第一个解决方案一样,获取

DataTable
,但将控件绑定到多用途
BindingSource

private void LoadClient()
{
    cbClient.DisplayMember = "Value";
    cbClient.ValueMember = "Id";
    cbClient.DataSource = new BindingSource(GetDataTable(), null);
}

private void txtFilterClient_TextChanged(object sender, EventArgs e)
{
    if (cbClient.DataSource is BindingSource bs)
    {
        var str = txtFilterClient.Text.Trim();

        bs.Filter = string.IsNullOrEmpty(str)
            ? null
            : $"Value LIKE '%{str}%'";
    }
}


列表<

T
>
如果您需要操作
List<T>
并且您有一个如下模型:

public class IdValueReadModel
{
    public int Id { get; set; }
    public string Value { get; set; }
}

然后您可以执行

Linq
查询来过滤此处类型为
List<IdValueReadModel>
的数据源。当清除过滤器时,您需要将原始列表缓存在类字段中作为数据源。运行
Linq
查询来绑定 new 过滤列表。

private List<IdValueReadModel> clientCache;

private void LoadClient()
{
    clientCache = // Get/assign the list...
    cbClient.DisplayMember = "Value";
    cbClient.ValueMember = "Id";
    cbClient.DataSource = clientCache;
}

private void txtFilterClient_TextChanged(object sender, EventArgs e)
{
    var str = txtFilterClient.Text.Trim().ToLower();

    cbClient.DataSource = string.IsNullOrEmpty(str)
        ? clientCache
        : clientCache
        .Where(c => c.Value.ToLower().Contains(str))
        .ToList();
}
© www.soinside.com 2019 - 2024. All rights reserved.