如何重构此代码以搜索 BindingList 的多个属性?
How to refactor this code to search through multiple properties of a BindingList?
我在 Windows 表单中创建了一个搜索按钮和一个关联的文本框,以通过 DataGridView 进行搜索。 DGV 在 BindingList 中显示信息。 BindingList 具有 PartID、Name、Price、Instock、Min 和 Max 属性,它们是 int、string、decimal、int、int 和 int 类型。我可以让搜索正常运行,但代码本身看起来很笨重。如何使用更少的代码在 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;
}
}
例如,您可以这样重构:
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
DataGridView Filter a BindingSource with a List of object as DataSource
Filtering BindingList
C# filter objects with BindingSource in DataGridView
我在 Windows 表单中创建了一个搜索按钮和一个关联的文本框,以通过 DataGridView 进行搜索。 DGV 在 BindingList 中显示信息。 BindingList 具有 PartID、Name、Price、Instock、Min 和 Max 属性,它们是 int、string、decimal、int、int 和 int 类型。我可以让搜索正常运行,但代码本身看起来很笨重。如何使用更少的代码在 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;
}
}
例如,您可以这样重构:
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
DataGridView Filter a BindingSource with a List of object as DataSource
Filtering BindingList
C# filter objects with BindingSource in DataGridView