2010-03-21 4 views
3

dans un autre sujet, j'ai trébuché sur cette solution très élégante par Darin Dimitrov pour filtrer l'DataSource d'un ComboBox avec la sélection d'un autre ComboBox: how to filter combobox in combobox using c#L'utilisation de Linq pour filtrer un ComboBox.DataSource?

combo2.DataSource = ((IEnumerable<string>)c.DataSource) 
.Where(x => x == (string)combo1.SelectedValue); 

Je voudrais faire quelque chose de semblable, mais au lieu de filtrer par un second combobox, je voudrais filtrer par le texte d'un TextBox. (Fondamentalement, au lieu de choisir à partir d'un deuxième ComboBox, l'utilisateur entre simplement son filtre dans un TextBox). Cependant, il s'est avéré ne pas être aussi simple que je l'avais espéré. J'ai essayé des choses comme ce qui suit, mais a lamentablement échoué:

 cbWohndresse.DataSource = ((IEnumerable<DataSet>)ds) 
      .Where(x => x.Tables["Adresse"].Select("AdrLabel LIKE '%TEST%'")); 
     cbWohndresse.DisplayMember = "Adresse.AdrLabel"; 
     cbWohndresse.ValueMember = "Adresse.adress_id"; 

ds est le DataSet que je voudrais utiliser comme source de données filtrée. "Adresse" est l'un DataTable dans ce DataSet. Il contient un DataColumn "AdrLabel". Maintenant, je voudrais afficher seulement ces "AdrLabel", qui contiennent la chaîne de l'entrée de l'utilisateur. (Actuellement,% TEST% remplace le textbox.text.)

Le code ci-dessus échoue car l'expression lambda ne retourne pas Bool. Mais je suis sûr, il y a aussi d'autres problèmes (quel type devrais-je utiliser pour IEnumerable? Maintenant, c'est DataSet, mais Darin a utilisé String.) Comment puis-je convertir un DataSet en une chaîne

Oui, je suis autant newbyish comme ça, mon expérience est "vide", et publiquement ainsi, alors s'il vous plaît pardonnez-moi mes questions plutôt stupides

Votre aide est grandement appréciée, parce que je ne peux pas résoudre cela par moi-même (déjà essayé dur).

Merci beaucoup!

Pesche

P.S. J'utilise seulement Linq pour réaliser un filtre non compliqué pour le ComboBox (en évitant une vue). Le reste n'est pas basé sur Linq, mais sur oldstyle Ado.NET (ds est rempli par un SqlDataAdapter), si c'est important.

Répondre

4

LINQ ne me semble pas une solution évidente ici. Vos données sont déjà chargées dans une structure DataSet, vous devriez donc être en mesure de faire quelque chose comme ceci:

var adresse = ds.Tables["Adresse"]; 
adresse.DefaultView.RowFilter = "AdrLabel LIKE '%TEST%'"; 

cbWohndresse.DataSource = adresse; 
cbWohndresse.DisplayMember = "AdrLabel"; 
cbWohndresse.ValueMember = "adress_id" 
cbWohndresse.DataBind(); 

Pour résoudre les problèmes réels de votre code actuel:

  1. Si ds est de type DataSet , le couler à IEnumerable<DataSet> échouera.
  2. DataTable.Select renvoie un tableau de lignes, pas un booléen.
  3. En ignorant # 1 et # 2, votre appel Where() retournera zéro, une ou plusieurs instances DataSet ayant chacune une table nommée "Adresse" avec au moins une ligne correspondant au filtre. Par conséquent, vous finissez par lier votre contrôle de présentation à un ensemble de DataSet instances, ce qui est pas ce dont vous avez besoin.
+0

Merci beaucoup pour votre rediffusion ultra-rapide! Cela ressemble à une approche directe que je ne connaissais pas, avant! Aussi l'analyse du problème réel est très intéressante pour moi - puisque je suis un débutant et désireux d'apprendre :) –

1

Si vous souhaitez utiliser LINQ, vous devez ajouter une référence System.Data.DataSetExtensions. Vous pouvez ensuite interroger votre DataSet d'une manière "linqish".

Le billet de blog Querying DataSets – Introduction to LINQ to DataSet par Erick Thompson, un PM chez Microsoft est une bonne introduction à LINQ à DataSets

Voici un exemple très brut:

XAML

<StackPanel> 

    <TextBox x:Name="MyFilter" /> 

    <ComboBox x:Name="MyComboBox" 
       ItemsSource="{Binding}" 
       DisplayMemberPath="AdrLabel" /> 

    <Button Click="OnFilterClick">Filter</Button> 

</StackPanel> 

code Derrière

public partial class FilteredDataSet : Window 
{ 
    public FilteredDataSet() 
    { 
     InitializeComponent(); 

     CreateDataContext(); 
     MyComboBox.DataContext = MyDataSet.Tables[0]; 
    } 

    private DataSet MyDataSet { get; set; } 
    private void CreateDataContext() 
    { 
     var ds = new DataSet(); 
     var dt = new DataTable("Adresse"); 
     ds.Tables.Add(dt); 

     var dc = new DataColumn("AdrLabel"); 
     dt.Columns.Add(dc); 

     DataRow dr = dt.NewRow(); 
     dr[0] = "one"; 
     dt.Rows.Add(dr); 

     dr = dt.NewRow(); 
     dr[0] = "honed"; 
     dt.Rows.Add(dr); 

     dr = dt.NewRow(); 
     dr[0] = "obiwone"; 
     dt.Rows.Add(dr); 

     dr = dt.NewRow(); 
     dr[0] = "won"; 
     dt.Rows.Add(dr); 

     MyDataSet = ds; 

    } 
    private void OnFilterClick(object sender, RoutedEventArgs e) 
    { 
     string filter = MyFilter.Text; 

     var context = MyDataSet.Tables[0].AsEnumerable() 
      .Where(dr => dr.Field<string>("AdrLabel").Contains(filter)) 
      .Select(dr => dr.Field<string>("AdrLabel")); 

     MyComboBox.DisplayMemberPath = string.Empty; 

     MyComboBox.DataContext = context; 
    } 
} 
+0

Mes nombreux remerciements vont aussi à vous! Cela semble vraiment être un super endroit avec des gens très serviables et sympathiques. Maintenant, j'ai différentes approches à mon problème, en me donnant le meilleur aperçu possible. Merci beaucoup! Malheureusement, je n'ai pas encore assez de réputation pour voter. –

+0

Revenez, visitez, contribuez :) Assurez-vous d'accepter les réponses à vos questions. Et bienvenue! –

+0

Ehm, je peux accepter deux réponses? La coche verte ne collera qu'à une seule réponse ... –

Questions connexes