我有List<>
个对象,其类型为我的类Car
。类Car
具有12个属性。我有7个TextBox
,用户可以在此处输入搜索值(某些属性)。如何通过该列表进行搜索以获得与输入的所有数据匹配的对象?
我已经尝试过这样的事情:
foreach (Car x in Cars)
{
//then here I question every attribute with search value which match I add to new List<>
if(x.color == textBox1.Text) search.Add(x);
}
textBox1
是用户输入的值之一。当用户仅输入一个值时,此方法有效。如果输入两个值,它将找到具有两个值中任何一个的所有对象。但是我想找到两个值都匹配的对象。
答案 0 :(得分:0)
如果要检查是否输入了过滤器值,请执行此操作
IEnumerable<Car> filteredCars = Cars;
if(!String.IsNullOrWhiteSpace(textBox1.Text))
filteredCars = filteredCars.Where(car=>car.param == textBox1.Text);
if(!String.IsNullOrWhiteSpace(textBox2.Text))
filteredCars = filteredCars.Where(car=>car.param2 == textBox2.Text);
最后
var result = filteredCars.ToList()
仅执行一次ToList
(最后一次)
答案 1 :(得分:0)
我想你想要这样的结果吗?
我没有自动生成TextBox
,但是那很容易。
MainWindow.xaml
<StackPanel x:Name="MainGrid" Width="200" Margin="100">
<TextBlock Text="Color" />
<TextBox x:Name="ColorTextBox"></TextBox>
<TextBlock Text="Make" />
<TextBox x:Name="MakeTextBox"></TextBox>
<TextBlock Text="Interior" />
<TextBox x:Name="InteriorTextBox"></TextBox>
<Button x:Name="SearchButton" Content="Search" Click="SearchButton_Click"></Button>
<TextBlock x:Name="SearchResultTextBlock"></TextBlock>
</StackPanel>
MainWindow.xaml.cs
private void SearchButton_Click(object sender, RoutedEventArgs e)
{
Car[] allCars = new Car[] // Sample list of cars
{
new Car
{
Color = "Green",
Make = "Ford",
Interior = "Stone"
},
new Car
{
Color = "Green",
Make = "Ford",
Interior = "Wood"
},
new Car
{
Color = "Black",
Make = "Cadillac",
Interior = "Stone"
},
new Car
{
Color = "Black",
Make = "Volvo",
Interior = "Stone"
},
new Car
{
Color = "Green",
Make = "Volvo",
Interior = "Wood"
},
new Car
{
Color = "Green",
Make = "Volvo",
Interior = "Plastic"
},
};
var result = _filterWithInputs(allCars); // Search the list
SearchResultTextBlock.Text = $"Found {result.Length} matching cars."; // Output
}
private Car[] _filterWithInputs(IEnumerable<Car> allCars)
{
List<Car> result = new List<Car>();
// Get the TextBoxes from the viow
List<TextBox> textBoxes = new List<TextBox>();
foreach (var mainGridChild in MainGrid.Children)
{
if(mainGridChild is TextBox)
textBoxes.Add(mainGridChild as TextBox);
}
// Search the allCars collection.
foreach (var car in allCars)
{
if (_checkCarAgainstNamedTextBoxes(car, textBoxes))
result.Add(car);
}
Debug.WriteLine($"Found {result.Count} matching cars.");
// Return the result as a fixed-size array.
return result.ToArray();
}
private static bool _checkCarAgainstNamedTextBoxes(Car car, IEnumerable<TextBox> textBoxes)
{
foreach (TextBox textBox in textBoxes)
{
// Skip empty TextBokes (succees)
if(string.IsNullOrWhiteSpace(textBox.Text))
continue;
var propertyName = textBox.Name.Replace("TextBox", "");
// Assume all Car properties are strings
var val = car.GetType().GetProperty(propertyName)?.GetValue(car) as string;
// If the text doesn't match (case-sesitive) return false
// No need to check any more properties after first fail.
if (val != textBox.Text)
return false;
}
return true; // Everything succeeded!
}
神奇之处在于_checkCarAgainstNamedTextBoxes
,其中将TextBokes的前缀与Car类的属性名称进行比较。
如果将TextBox
命名为ColorTextBox
,则将其值与汽车的Color
属性进行比较。
文本框必须直接位于MainGrid
下才能显示在“儿童”集合中。递归很容易搜索多个级别。
答案 2 :(得分:0)
我将创建一个可以处理null的参数值列表,并在单个查询中执行:
string color = String.IsNullOrEmpty(textColor.Text) ? null : textColor.Text;
string engine = String.IsNullOrEmpty(textEngine.Text) ? null : textEngine.Text;
var filteredList = cars.Where(c => (color == null || c.Color == color) &&
(engine == null || c.Engine == engine)).ToList();
对其他文本框执行相同的操作。
答案 3 :(得分:-1)
使用LINQ时,可以根据所选条件逐步扩展查询:
$end
之所以可行,是因为您可以修改LINQ查询,直到实现它为止。在这种情况下,您在执行之前先在 之前添加所有选定的过滤条件。最后一步,您用var carsQry =
from car in Cars
select car;
//Filter by color
if (!String.IsNullOrWhiteSpace(textBox1.Text)) {
carsQry =
from car in carsQry
where cars.color == textBox1.Text.Trim()
select car;
}
//...repeat step above for all other filter criteria...
List<Car> filteredCars = carsQry.ToList();
实现(=执行)它。返回的列表将包含您过滤的项目。