2009-05-24 7 views
4

J'ai donc commencé à construire une petite application de test pour tester les expressions lambda. J'ai trouvé plusieurs exemples ici et ailleurs mais je ne les ai tout simplement pas compris.Expressions lambda de construction dynamique

Quelqu'un peut-il expliquer ma façon de construire une expression en utilisant des zones de texte ou d'autres variables?

Ma liste de test

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

travail lambda Expression

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

Comment puis-je construire les expressions dynamiquement?

Quelque chose comme lPeople.Where(p => p.LastName == Textbox.Text); (ce qui bien sûr ne fonctionne pas)

Merci!

Edit: ajout de code à la solution ci-dessous

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

Je suppose que vous avez mal saisi le nom du contrôle de zone de texte. Est-ce TextBox1? :) – shahkalpesh

Répondre

5

"qui bien sûr ne fonctionne pas"

Qu'est-ce qui se passe quand vous essayez? Par le regard, c'est le genre de chose que je fais tout le temps.

Pour passer des opérations en fonction d'un ComboBox spécifiant l'opérateur:

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

Le code qui convertit la chaîne d'âge dans un int jetteront si l'utilisateur saisit quelque chose qui ne peut pas être converti. Rechercher TryParse pour éviter les exceptions.

+0

Omg, je suis tellement désolé! ça marche :) mais qu'en est-il des opérants? –

+0

Ok ... voulez-vous dire que vous voulez choisir l'opérateur (==, <, >,! =, Etc.) basé sur l'état des contrôles de dialogue? (Cela irait beaucoup plus vite si vous expliquiez très attentivement ce que vous essayez d'accomplir!) –

+0

Salut Earwicker, oui, je voudrais ça. J'ai une interface utilisateur où l'utilisateur peut choisir de filtrer une liste de personnes par LastName et c'est-à-dire par Age. J'ai un ListBox où ils peuvent sélectionner>, = et

2

Votre exemple d'expression lambda fonctionnera. Quelle dynamique avez-vous besoin d'être? Si vous avez une interface utilisateur statique des « filtres » à appliquer à une collection, vous pouvez créer un code similaire à ce qui suit:

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

Si vous voulez que le consommateur de votre source de données pour appliquer des expressions vraiment dynamiques (les permettre la possibilité de choisir d'autres champs à filtrer et les expressions à utiliser), c'est une fonctionnalité plus compliquée à implémenter à l'aide d'un outil de création de prédicat ou d'objets d'expression LINQ.

+0

En fait, je veux aussi modifier les opérateurs. –

2

Il ne devrait y avoir rien de mal à la façon dont vous y parvenez. J'ai créé une application Windows Forms simple avec un TextBox, un Button et un DataGridView (avec les noms textBox1, button1 et dgv_1 respectivement.)

Voici le code que j'utilisé pour le fichier Form1.cs qui a fonctionné comme prévu:

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

Salut John, exactement la chose que j'ai faite :) –

1

En cas de choix de l'utilisateur dynamique, je pense qu'une solution plus élégante plutôt que d'utiliser si les blocs seraient de déclarer une variable

Func<People, bool> expFilter; 

définir sa valeur en fonction du choix de l'utilisateur

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

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

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

, puis passez-le à la clause Where:

result = lPeople.Where(expFilter);   
Questions connexes