tags:

views:

1214

answers:

5

So, I started to build a small test application to test lambda expressions. I found several examples here and elsewhere but I just don't get them.

Can anybody explain my how to build an expression by using textboxes or any other variables?

My Test List

        List<People> lPeople = new List<People> 
        {
            new People { Name= "Jean", LastName = "Borrow", Age= 21 } ,
            new People { Name= "Dean", LastName = "Torrow", Age= 20 }
        };

Working lambda Expression

        IEnumerable<People> result = lPeople.Where(p => p.Age < 21);
        dgv_1.DataSource = result.ToList();
        dgv_1.Update();

How can I build the expressions dynamically?

Something like lPeople.Where(p => p.LastName == Textbox.Text); (which of course doesn't work)

Thanks!

Edit: Added some code to the solution below

        Int32 iAge;
        Boolean bSuc = Int32.TryParse(tb_filter_age.Text, out iAge);
        if (!bSuc)
        {
            iAge = 0;
        }
+2  A: 

"which of course doesn't work"

What happens when you try it? By the look of it, that's the kind of thing I do all the time.

To switch operations based on a ComboBox specifying the operator:

int age = int.Parse(textBoxAge.Text);

IEnumerable<People> result;
if (comboBoxOperator.Text == "=")
    result = lPeople.Where(p => p.Age == age);
else if (comboBoxOperator.Text == "<")
    result = lPeople.Where(p => p.Age < age);
else
    result = lPeople.Where(p => p.Age > age);

dgv_1.DataSource = result.ToList();
dgv_1.Update();

The code that converts the age string into an int will throw if the user enters something that can't be converted. Look up TryParse to avoid exceptions.

Daniel Earwicker
Omg, I'm so sorry! it does work :) but what about the operants?
Henrik P. Hessel
Okay... do you mean that you want to choose the operator (==, <, >, !=, etc.) based on the state of dialog controls? (This would all go much quicker if you explained really carefully what you're trying to achieve!)
Daniel Earwicker
Hi Earwicker, yes, I would like that. I having an UI where the user can choose to filter a list of people by LastName and i.e. by the Age. I have a ListBox where they can select >, = and < and a Textbox where they can input an age.
Henrik P. Hessel
I've updated my answer, but it's nothing fancy.
Daniel Earwicker
To help others users: Int32 iAge; Boolean bSuc = Int32.TryParse(tb_filter_age.Text, out iAge);if (!bSuc){ iAge = 0;}
Henrik P. Hessel
+1  A: 

You can use the Linq Dynamic Query Library to accomplish this. See the following blog post from Scott Guthrie for more information:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Robert Harvey
+2  A: 

Try the Predicate Builder at http://www.albahari.com/nutshell/predicatebuilder.aspx

I used it to make an advanced search where the user could keep adding optional search criteria.

Sudhir Jonathan
+1  A: 

Your example lambda expression will work. How dynamic do you need it to be? If you have a static UI of 'filters' to apply to a collection, you can create code similar to the following:

IEnumerable<People> result = lPeople;
if (txtLastName.Text.Trim().Length != 0) 
    result = result.Where(p => p.LastName == txtLastName.Text); 
if (chkSeniors.Checked) 
    result = result.Where(p => p.Age >= 65);
dgv_1.DataSource = result.ToList();
dgv_1.Update();

If you want the consumer of your data source to apply truly dynamic expressions (afford them the ability to choose other fields to filter and the expressions to use), that's a more complicated feature to implement using a predicate builder tool or LINQ Expression objects.

Jason
Actually I want to modify the operators, too.
Henrik P. Hessel
+1  A: 

There should be nothing wrong with the way you're going about it. I have created a simple Windows Forms Application with a TextBox, a Button, and a DataGridView (with names textBox1, button1, and dgv_1 respectively.)

Here is the code I used for the Form1.cs file that worked as expected:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        List<People> lPeople = new List<People> 
        {
            new People { Name= "Jean", LastName = "Borrow", Age= 21 } ,
            new People { Name= "Dean", LastName = "Torrow", Age= 20 }
        };

        IEnumerable<People> result = lPeople.Where(p => p.Name == textBox1.Text);

        dgv_1.DataSource = result.ToList();
        dgv_1.Update();
    }
}    

public class People
{
    public string Name { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}
John Rasch
Hi John, exactly the thing I did :)
Henrik P. Hessel