winforms DataSource.DefaultView.RowFilter不存在

nfeuvbwi  于 2023-03-31  发布在  其他
关注(0)|答案(1)|浏览(118)

我在我的项目中有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";
}

数据在那里:

slmsl1lt

slmsl1lt1#

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

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

这一行在你的旧的www.example.com项目中是有效vb.net的,因为你已经有了Option Strict Off,它允许隐式收缩转换,后期绑定和导致object类型的隐式类型。如果你想写好的vb.net代码,并避免这样做可能的错误和bug,你不应该允许提到的。在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}%'";
    }
}

BindingSource

与第一个解决方案一样,获取一个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查询来绑定一个新的过滤列表。

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();
}

相关问题