2010-07-14 6 views
4

Je travaille avec 2 listes dans une classe backend. Chaque liste est un type différent. Souhaitez présenter à l'utilisateur une liste unique (contenant une union des deux listes) dont un élément de cette liste est sélectionné les détails de l'élément apparaissent.WPF Fusionner ItemsSource Listes

Le code ressemblera:

Ma classe de back-end ressemble somethings comme celui-ci

public ObservableCollection<Person> People {get;} 
public ObservableCollection<Product> Products {get;} 

Mon XAML Attend quelque chose comme ça

<ListBox x:Name="TheListBox" ItemsSource={Some Expression to merge People and Products}> 
    <ListBox.Resources> 
     People and Product Data Templates 
    </ListBox.Resources> 
</ListBox> 
     ... 
<ContentControl Content={Binding ElementName=TheListBox, Path=SelectedItem }> 
    <ContentControl.Resources> 
     Data Templates for showing People and Product details 
    </ContentControl.Resources> 
</ContentControl> 

Toutes les suggestions?

+0

Je cherche quelque chose de similaire que je peux utiliser directement à partir du balisage et qui ne pollue pas mon interface de vue. Il devrait essentiellement résoudre l'incompatibilité entre les éléments fournis par le modèle de vue, qui peut être plusieurs collections ou seulement quelques propriétés indépendantes et ce que WPF attend, qui est un seul énumérable. Idéalement, je voudrais même ajouter des éléments directement dans le balisage qui ne correspond même pas à quelque chose dans le modèle de vue, mais fusionné dans la même liste. – Christo

Répondre

0

J'ai trouvé un billet de blog here qui m'a le plus marqué. J'ai utilisé les auteurs AggregateCollection avec un multivalueconverter pour faire le travail.

2

Je ne comprends pas pourquoi vous n'avez pas seulement d'exposer une propriété comme celui-ci dans votre ViewModel:

ObservableCollection<object> Items 
{ 
    get 
    { 
    var list = new ObservableCollection<object>(People); 
    list.Add(Product); 
    return list; 
    } 
} 

puis dans votre XAML vous faites ceci:

<ListBox x:Name="TheListBox" ItemsSource={Binding Items}> 
    <ListBox.Resources> 
     People and Product Data Templates 
    </ListBox.Resources> 
</ListBox> 
     ... 
<ContentControl Content={Binding ElementName=TheListBox, Path=SelectedItem }> 
    <ContentControl.Resources> 
     Data Templates for showing People and Product details 
    </ContentControl.Resources> 
</ContentControl> 

MISE À JOUR :

Si vous devez manipuler votre modèle différemment, procédez comme suit:

ObservableCollection<object> _Items 
ObservableCollection<object> Items 
{ 
    get 
    { 
    if (_Items == null) 
    { 
     _Items = new ObservableCollection<object>(); 
     _Items.CollectionChanged += EventHandler(Changed); 
    } 
    return _Items; 
    } 
    set 
    { 
    _Items = value; 
    _Items.CollectionChanged += new CollectionChangedEventHandler(Changed); 
    } 
} 

void Changed(object sender,CollectionChangedEventArgs e) 
{ 
    foreach(var item in e.NewValues) 
    { 
    if (item is Person) 
     Persons.Add((Person)item); 
    else if (item is Product) 
     Products.Add((Product)item); 
    } 
} 

Ceci est juste un exemple. Mais si vous modifiez ce qui précède pour répondre à vos besoins, cela pourrait vous aider à atteindre votre objectif.

+0

J'ai envisagé de le faire d'une manière similaire à ce que vous avez proposé. Ce qui compliquait mon scénario était que j'avais besoin d'un moyen d'ajouter et de supprimer des éléments des listes via l'interface utilisateur. – Gus

+0

vérifier la mise à jour – Jose

Questions connexes