2009-07-10 7 views
0

J'ai rencontré un problème avec mon modèle pour la liaison de données dans WPF. J'ai un objet qui a une collection d'objets (Variable), et chacun a à son tour une autre collection d'objets (VariableCode). Ce que je dois pouvoir faire est en quelque sorte d'exposer une seule collection à partir de l'objet de plus haut niveau - qui est une fusion des collections de niveau les plus bas (VariableCode) où chaque objet membre remplit une condition. Alors que je peux lier cette collection à un ListBox, qui devrait afficher VariableCodes qui appartiennent à 1 ou plusieurs variables.Expose plusieurs collections en tant que collection unique

Ainsi, le code ressemble à ceci:

public class CrossTab 
{ 
    public VariableList Variables{get; set;} 
} 
public class Variable 
{ 
    public VariableCodeList VariableCodes{get; set;} 
} 
public class VariableCode 
{ 
    public bool IsShown{get; set;} 
} 

Ce que je voudrais vraiment faire est d'exposer une propriété sur CrossTab (de préférence un ObservableCollection < VariableCode>) qui est une vue sur tout le contenu VariableCodes où IsShown == vrai. Actuellement, il s'agit de collections distinctes, chacune étant contenue dans leur propre objet Variable.

public class CrossTab 
{ 
    public ObservableCollection<VariableCode> ShownCodes 
    { 
    get 
    { 
     //This is where I could picture some brute force looping 
     // and building of a new collection - but that's not really 
     // what I'm after. What I want is a live view on the data 
     // that's in there 
    } 
    } 
} 

Le code de la force brute que je caressait qui retourne les données correctes - pas aussi une vue en direct, mais plutôt comme une collection statique.

ObservableCollection<VariableCode> output = new ...(); 
Variables.ForEach(v => 
    v.VariableCodes.Where(vc => vc.IsShown) 
    .ForEach(vc => output.Add(vc)) 
); 
return output; 

Pensées? Une telle chose est possible?

Répondre

1

Vous pouvez utiliser la méthode SelectMany Linq pour y parvenir, comme suit:

public class CrossTab 
{ 
    public VariableList Variables { get; set; } 

    public ObservableCollection<VariableCode> ShownCodes 
    { 
     get 
     { 
      return new ObservableCollection<VariableCode>(
       Variables 
        .SelectMany(variable => variable.VariableCodes) 
        .Where(code => code.IsShown) 
       ); 
     } 
    } 
} 
+0

Bien mis en contexte. –

1

Avez-vous envisagé d'utiliser une requête LINQ pour obtenir le résultat dont vous avez besoin dans votre structure de données plutôt que d'ajouter plus de propriétés?

3

Je pense que SelectMany (LINQ) est ce que vous cherchez. Voir si this aide.

Essayez d'utiliser le lien ci-dessus pour votre exemple & en l'écrivant dans SO (sans compilateur).
je serai étonné de voir, si cela fonctionne;)

var allTeams = 
from v in Variables.SelectMany(v => v.VariableCodes).SelectMany(vc) 
where vc.IsShown == true; 
select vc; 
+0

également correct. Merci. –

0

Je pense PRÉPONDÉRANTS l'opérateur d'index serait une bonne idée. Le code suivant est un exemple de comment vous pouvez faire cela. Ce code est entièrement testé et détecte même les exceptions "IndexOutOfRange".

class Collection 
    { 
    //         [0] [1] 
    static String[] a1 = new String[] { "one", "two" }; 
    //         [2]  [3] 
    static String[] a2 = new String[] { "three", "four" }; 
    //         [4]  [5] 
    static String[] a3 = new String[] { "five", "six" }; 

    static Object[] collections = new Object[] { a1, a2, a3 }; 

    public String this[int i] 
     { 
     get 
     { 
     int add_to_index = 0; 
     int collection_num = 0; 

     int calculated_index = i - add_to_index; 

     for (String[] pointer = (String[])collections[collection_num]; 
      1 == 1; 
      pointer = (String[])collections[++collection_num], 
      calculated_index = i - add_to_index) 
      { 
      if (calculated_index < pointer.Length) 
       return pointer[calculated_index]; 
      else if (collection_num == (collections.Length - 1)) 
       throw new IndexOutOfRangeException(); 
      add_to_index += pointer.Length; 
      } 

     throw new IndexOutOfRangeException(); 
     } 
     set { throw new NotImplementedException(); } 
     } 

    } 
Questions connexes