【问题标题】:How to refactor this code to search through multiple properties of a BindingList?如何重构此代码以搜索 BindingList 的多个属性?
【发布时间】:2021-08-29 10:18:42
【问题描述】:

我在 Windows 窗体中创建了一个搜索按钮和一个关联的 texbox,以通过 DataGridView 进行搜索。 DGV 在 BindingList 中显示信息。 BindingList 具有类型为 int、string、decimal、int、int 和 int 的属性 PartID、Name、Price、Instock、Min 和 Max。我可以让搜索正常运行,但代码本身看起来很笨拙。如何使用更少的代码在 BindingList 中进行“for”循环搜索?

for (int i = 0; i < Inventory.AllParts.Count; i++)
{
    //I would like to condense this if statement into one line of code
    if (Inventory.AllParts[i].PartID.ToString().Contains(partsSearchTextBox.Text.ToString())
        || Inventory.AllParts[i].Name.ToString().Contains(partsSearchTextBox.Text.ToString())
        || Inventory.AllParts[i].Price.ToString().Contains(partsSearchTextBox.Text.ToString())
        || Inventory.AllParts[i].Instock.ToString().Contains(partsSearchTextBox.Text.ToString())
        || Inventory.AllParts[i].Min.ToString().Contains(partsSearchTextBox.Text.ToString())
        || Inventory.AllParts[i].Max.ToString().Contains(partsSearchTextBox.Text.ToString()))
    {
        dgvParts.Rows[i].Selected = true;
        found = true;
    }
}

【问题讨论】:

  • 如果“BindList”对数据使用类的集合,为什么不搜索该集合呢?该类可以提供您测试的复合可搜索字符串。

标签: c# search filter textbox bindinglist


【解决方案1】:

你可以像这样重构:

bool CheckOR(Func<string, bool> predicate, params object[] values)
{
  //if ( predicate == null ) return false;
  foreach ( object value in values )
    if ( predicate(value.ToString()) )
      return true;
  return false;
}

for ( int i = 0; i < Inventory.AllParts.Count; i++ )
{
  if ( CheckOR(s => s.Contains(partsSearchTextBox.Text)
               Inventory.AllParts[i].PartID,
               Inventory.AllParts[i].Name,
               Inventory.AllParts[i].Price,
               Inventory.AllParts[i].Instock,
               Inventory.AllParts[i].Min,
               Inventory.AllParts[i].Max) )
  {
    dgvParts.Rows[i].Selected = true;
    found = true;
  }
}

使用 Linq:

bool CheckOR(Func<string, bool> predicate, params object[] values)
{
  return values.Any(v => predicate(v.ToString()));
}

简化为:

for ( int i = 0; i < Inventory.AllParts.Count; i++ )
{
  var values = new object[]
  {
    Inventory.AllParts[i].PartID,
    Inventory.AllParts[i].Name,
    Inventory.AllParts[i].Price,
    Inventory.AllParts[i].Instock,
    Inventory.AllParts[i].Min,
    Inventory.AllParts[i].Max
  };
  if ( values.Any(v => v.ToString().Contains(partsSearchTextBox.Text)) )
  {
    dgvParts.Rows[i].Selected = true;
    found = true;
  }
}

如果可能,需要更多细节来进一步改进,也许可以使用反射,因为如果检查了所有字段,我们就可以解析属性。或者可以使用带有属性名称的预定义数组。

您还可以使用BindingListView 使用过滤器,效果很好。

BindingSource.Filter,但它不适用于标准BindingList

相关问题

Applying a filter to a BindingSource, but it doesn't work

Filter BindingSource when DataSource is a BindingList

DataGridView Filter a BindingSource with a List of object as DataSource

Filtering BindingList

Filtering BindingSource and DataGridView

C# filter objects with BindingSource in DataGridView

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多