【问题标题】:How to filter DataGridView using TextBoxes and list as DataSource using Dapper?如何使用 TextBoxes 过滤 DataGridView 并使用 Dapper 将其列为 DataSource?
【发布时间】:2020-12-04 17:03:03
【问题描述】:

我的目标是使用 TextBoxes 过滤 datagridview。

这是我当前的代码。

表格

// Load the datagrid with Product Specifications
List<ProductSpecificationModel> productSpecificationsList = new List<ProductSpecificationModel>();
public void refreshData()
{
    DataAccess db = new DataAccess();
    productSpecificationsList = db.GetSpecifications();
    productSpecGrid.DataSource = productSpecificationsList;  
}

我从外部类填写列表:

数据访问

public List<ProductSpecificationModel> GetSpecifications()
{
    using(MySqlConnection conn = new MySqlConnection(ConnectionString.ConnString))
    {
        var output = conn.Query<ProductSpecificationModel>(@"
                SELECT
                    ID,
                    ProductCode,
                    ProductDescription
                FROM ProductSpecifications;").ToList();
        return output;
    }
}

型号

public class ProductSpecificationModel
{
    public int ID { get; set; }
    [DisplayName("Product Code")]
    public string ProductCode { get; set; }
    [DisplayName("Product Description")]
    public string ProductDescription { get; set; }    
}

我如何尝试过滤

private void searchFunction()
{
    List<string> parts = new List<string>();
    if (filterCode.Text.Length > 0)
    {
        parts.Add("ProductCode like '%" + filterCode.Text + "%'");
    }
    if (filterDescription.Text.Length > 0)
    {
        parts.Add("ProductDescription like '%" + filterDescription.Text + "%'");
    }

    (productSpecGrid.DataSource as DataView).RowFilter = string.Join(" and ", parts);

}

private void searchBtn_Click(object sender, EventArgs e)
{
    searchFunction();
}

错误

当我点击search 时,会显示:

An unhandled exception of type 'System.NullReferenceException' occurred in Application.exe
Additional information: Object reference not set to an instance of an object.

试试 2

使用这些答案

https://stackoverflow.com/a/26608951/12485722

也试过这个:

// From this
(productSpecGrid.DataSource as DataView).RowFilter = string.Join(" and ", parts);

>>>>>

// To this
(productSpecGrid.DataSource as DataTable).DefaultView.RowFilter = string.Join(" and ", parts);

还有错误:

Application.exe 中出现“System.NullReferenceException”类型的未处理异常 附加信息:对象引用未设置为对象的实例。

【问题讨论】:

  • 您想使用调试器中断此异常以了解它发生的位置,并最终在您的过滤器中添加空检查(如果存在问题)以避免对空对象执行任何操作。
  • @Soleil-MathieuPrévot (productSpecGrid.DataSource as DataView).RowFilter = "ProductCode like '0001'"; 这会引发同样的错误......
  • 因为您正在转换为错误的类型。您的数据源是List&lt;ProductSpecificationModel&gt;,不是DataTable,也不是DataView。您需要在这里使用LINQ 来过滤列表。
  • @dr.null 没听说过LINQ 我去看看。
  • @dr.null 是这样的吗? stackoverflow.com/a/50479387/12485722

标签: c# dapper


【解决方案1】:

您收到此异常是因为您尝试将 DataSource 转换为错误的类型。

这里:

(productSpecGrid.DataSource as DataView)

这里:

(productSpecGrid.DataSource as DataTable)

所以,如果你声明一个像这样的变量:

var ds = (productSpecGrid.DataSource as DataView);

ds 产生 null 并尝试访问方法或设置 null 对象的属性会引发 System.NullReferenceException 异常。

.DataSource 的正确类型是:

List<ProductSpecificationModel>

所以正确的演员是:

(productSpecGrid.DataSource as List<ProductSpecificationModel>)

对于过滤器部分,当您使用List&lt;T&gt; 时,请使用LINQ 获取过滤列表并重置.DataSource 属性。

例如:

using System.Linq;

private List<ProductSpecificationModel> Filter(string productCode, string productDescription)
{
    if (!string.IsNullOrEmpty(productCode) && !string.IsNullOrEmpty(productDescription))
        return productSpecificationsList
            .Where(x => x.ProductCode
            .IndexOf(productCode, StringComparison.InvariantCultureIgnoreCase) >= 0 && x.ProductDescription
            .IndexOf(productDescription, StringComparison.InvariantCultureIgnoreCase) >= 0)
            .ToList();
    else if (!string.IsNullOrEmpty(productCode))
        return productSpecificationsList.Where(x => x.ProductCode
        .IndexOf(productCode, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();
    else if (!string.IsNullOrEmpty(productDescription))
        return productSpecificationsList.Where(x => x.ProductDescription
        .IndexOf(productDescription, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();
    else
        return productSpecificationsList;
}

... 并称之为:

productSpecGrid.DataSource = Filter(filterCode.Text, filterDescription.Text);

...并设置主列表:

productSpecGrid.DataSource = productSpecificationsList;

【讨论】:

    【解决方案2】:

    我发现了一种更短的过滤数据的方法。

    代码如下:

    private void filterCode_TextChanged(object sender, EventArgs e)
    {
        TextBox searchTextBox = sender as TextBox;
        var filteredList = productSpecificationsList.Where(c => c.ProductCode.Contains(filterCode.Text)).ToList();
    
        productSpecGrid.DataSource = filteredList;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-28
      • 2011-08-13
      • 2010-12-17
      • 2018-03-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      相关资源
      最近更新 更多