提问人:Arie 提问时间:3/22/2023 最后编辑:JimiArie 更新时间:10/15/2023 访问量:267
如何使用 DataTable.DefaultView.RowFilter 筛选项目
How to filter items with DataTable.DefaultView.RowFilter
问:
我的项目中绑定了 .我希望能够仅将项目筛选为与我在其他控件中键入的文本匹配的项目。我知道我可能会在我的旧 vb.net 项目中使用如下所示的以下属性。然而,当我尝试在我最近的 Visual Studio C# 项目中做同样的事情时,似乎不再被认可。如果这是不合时宜的,或者有任何其他方法,我该如何过滤项目?listbox
datasource
textbox
DefaultView.RowFilter
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";
}
数据在那里:
答:
澄清对上述问题的评论。
首先
listbox1.DataSource.DefaultView.RowFilter = "[Nummer] like '%" & lbSearchProd.Text.Trim()
此行在旧的 vb.net 项目中有效,因为您具有 Option Strict Off
,它允许隐式缩小转换、后期绑定和导致类型的隐式类型化。如果你想写出好的 vb.net 代码,并通过这样做来避免可能的错误和错误,你就不应该允许上述内容。在 c# 中,没有该选项。您需要将 强制转换为分配的对象实例的类型才能访问它。object
object
其次,你这里的数据源是一个 not .它们是两个不同的东西,你不能将可以为一个写的东西应用到另一个。您需要过滤 .List<T>
DataTable
Linq
List<T>
一些建议的解决方案。
DataTable
从数据访问中获取 a。像这样: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 与第一个解决方案一样,获取 but 将控件绑定到多用途 BindingSource
。DataTable
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}%'";
}
}
List<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();
}
评论
? null
if (string.IsNullOrEmpty(str)) //clear the filter else //set the filter;
.RowFilter = If(string.IsNullOrEmpty(str), Nothing, $"Value LIKE '%{str}%'")
评论
Option Strict Off
.DataSource
DataTable
(listbox1.DataSource as DataTable).DefaultView.RowFilter = ...
Option Strict On
BindingSource
BindingSource
DataTable
ListBox
Filter
BindingSource
System.NullReferenceException: 'Object reference not set to an instance of an object.' (... as System.Data.DataTable) returned null.
DataTable
DataView
.DataSource
LoadDataToClients()