Click here to Skip to main content
15,883,822 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to filter a object list (List<item>) bounded to a grid. Now I want to filter this list according to the user required.
I have combo box to select the field to filter and text box to enter the value. From there user can select ItemCode or Cost or any property relevant to Item class. Then how can I create the lambda expression according to the selected field and entered value.
Posted

Do a switch case and define your lambda expression based on your selected value.


C#
//note: update the type (sample format you want to get)
var result = new List<classnamehere>();
var filter = txtbox.Text;

switch (ddl.SelectedValue) {
   case "cost":
      //do filtering
      result = listSource.Find(s=>{s.cost == filter});
      break;
   case "itemcode":
      result = listSource.Find(s=>{s.itemcode == filter});
      break;
   default:
      result = listSource;
      break;
}</classnamehere>


Correct me if I'm wrong but I think you CANT dynamically construct lambda exp on your scenario.

Good luck!
 
Share this answer
 
v3
Try like this

This is the class on which you want to apply the filtering


public class ClassName
{
public string ItemCode { get; set; }
public string Cost { get; set; }
public override string ToString()
{
return "ItemCode " + ItemCode + ", Cost " + Cost;
}
}

This is the method to apply filtering

List<ClassName> getFiltered(List<ClassName> className, Func<ClassName, bool> func)
{
return className.Where(c => func(c)).ToList();
}

If you notice that we are passing a predicate named "func" which takes a parameter "ClassName" as input and return type is bool.

List<ClassName> i = new List<ClassName>();
i.Add(new ClassName { ItemCode = "1", Cost = "1" });
i.Add(new ClassName { ItemCode = "2", Cost = "2" });
i.Add(new ClassName { ItemCode = "3", Cost = "3" });
i.Add(new ClassName { ItemCode = "4", Cost = "4" });

List<ClassName> ClassName = getFiltered(i, t => t.Cost == txtFilterBox.Text);

Now see the second parameter "t => t.Cost == txtFilterBox.Text" which is accepting a parameter of type "ClassName" and return type is bool.



foreach (ClassName im in ClassName)
Response.Write(im.ToString());


I Think try with this, it should work for you
 
Share this answer
 
v5
Comments
Wayne Gaylard 10-May-11 3:25am    
There seems to be problem with the formatting of your code in your answer. There are portions missing from the Func declaration and extra tags floating all over. I would also suggest you explain how this will work as I tried to replicate your code but could not get it to compile, or even to make sense of it, to be honest.
Pong D. Panda 10-May-11 4:08am    
He uses Delegates on his filtering, but its more complicated this way. It can be done by a simple .Find(lambda exp)
Wayne Gaylard 10-May-11 4:18am    
It might be more complicated, but I was interested in a way of of doing this without the switch code, but this poster didn't reply or fix his answer.
Pong D. Panda 10-May-11 4:32am    
His code only filters the Cost. I almost got my cpu burned trying to figure out how to do it without using switch or using a lot of OR statements inside the lambda condition based on the combobox selected.
Wayne Gaylard 10-May-11 4:40am    
Yeah - I'm almost burning out my brain trying to come up with a solution. I tried using reflection, but it get's really complicated, and so the switch code ends up being the shortest route. But I don't give up - this should in theory be possible.
Reference Expression Trees[^]
C#
string filterText = "Hello";
string fieldName = "FieldName";
var type = typeof(YourClass);
ParameterExpression param = Expression.Parameter(type, "s");
var field = type.GetProperty(fieldName);
MemberExpression member = Expression.MakeMemberAccess(param,field);
ConstantExpression filter = Expression.Constant(filterText);
BinaryExpression compare = Expression.Equal(member, filter);
Expression<Func<YourClass, bool>> lambdaExpression =
    Expression.Lambda<Func<YourClass, bool>>(compare,param);

This should do it.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900