2009-05-24 2 views
4

Итак, я начал создавать небольшое тестовое приложение для тестирования лямбда-выражений. Я нашел несколько примеров здесь и в другом месте, но я их просто не получаю.Динамические строковые лямбда-выражения

Может ли кто-нибудь объяснить мне, как построить выражение, используя текстовые поля или любые другие переменные?

Мой список Тест

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.Age < 21); 
dgv_1.DataSource = result.ToList(); 
dgv_1.Update(); 

Как я могу построить выражения динамически?

Что-то вроде lPeople.Where(p => p.LastName == Textbox.Text); (который, конечно, не работает)

Спасибо!

Edit: Добавлен код для раствора ниже

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

Я думаю, вы могли бы ввести неверное имя элемента управления текстовым полем. Это TextBox1? :) – shahkalpesh

ответ

5

«который, конечно, не работает»

Что происходит, когда вы попробуете? По внешнему виду, это то, что я делаю все время.

Для переключения операций на основе ComboBox с указанием оператора:

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(); 

код, который преобразует возрастную строку в int бросят, если пользователь вводит что-то, что не может быть преобразован. Посмотрите вверх TryParse, чтобы избежать исключений.

+0

Омг, мне очень жаль! это работает :), но как насчет оперантов? –

+0

Хорошо ... вы имеете в виду, что хотите выбрать оператора (==, <, >,! = И т. Д.) На основе состояния элементов управления диалогового окна? (Это все пройдет гораздо быстрее, если вы очень тщательно объясните, чего вы пытаетесь достичь!) –

+0

Привет, Earwicker, да, я бы хотел этого. У меня есть пользовательский интерфейс, в котором пользователь может выбрать фильтрацию списка людей по LastName, а именно Age. У меня есть ListBox, где они могут выбрать>, = и <и текстовое поле, где они могут ввести возраст. –

5

Попробуйте предикат Builder в http://www.albahari.com/nutshell/predicatebuilder.aspx

Я использовал его, чтобы сделать расширенный поиск, где пользователь может сохранить, добавив дополнительные критерии поиска.

2

Ваш пример выражения лямбда будет работать. Насколько динамична она вам нужна? Если у вас есть статический пользовательский интерфейс «фильтры», чтобы применить к коллекции, вы можете создать код, подобный следующему:

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(); 

Если вы хотите, чтобы потребитель источника данных для применения настоящих динамических выражений (предоставить им возможность выбора других полей для фильтрации и используемых выражений), это более сложная функция для реализации с использованием инструмента построения предикатов или объектов выражения LINQ.

+0

На самом деле я тоже хочу изменить операторов. –

2

Не должно быть ничего плохого в том, как вы это делаете. Я создал простое приложение Windows Forms с TextBox, a Button и DataGridView (с именами textBox1, button1 и dgv_1 соответственно.)

Вот код, который я использовал для файла Form1.cs, который работал, как и ожидалось:

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; } 
} 
+0

Привет, Джон, именно то, что я сделал :) –

1

В случае динамического выбора пользователя, я считаю, что более элегантное решение, а затем использовать, если блоки будет объявлять переменная

Func<People, bool> expFilter; 

установить его значение на основе выбора пользователя

switch(comboBoxOperator.Text) 
{ 
    case "=": 
    expFilter = p => p.Age == age; 
    break; 

    case ">": 
    expFilter = p => p.Age > age; 
    break; 

    case "<": 
    expFilter = p => p.Age < age; 
    break; 
}  

, а затем передать его в положение Where:

result = lPeople.Where(expFilter);   
Смежные вопросы