2010-08-20 5 views
1

J'ai une zone de liste contenant de nombreux éléments et j'ai une liste déroulante en C# WPF. Je souhaite lier l'itemource de la combobox à celle de la listbox mais je veux filtrer certains items (c'est une source de données xml, je veux filtrer par le contenu d'un certain élément de l'élément item). Exemple d'item:Liaison de certains éléments de la zone de liste à la source d'objets combox

<Item> 
<itemtype>A</itemtype> 
<itemname>Name</itemname> 
</item> 

    <Item> 
<itemtype>B</itemtype> 
<itemname>Name</itemname> 
</item> 

je pensais d'ajouter manuellement un élément à la combobox lors de l'ajout d'un élément à la zone de liste mais la valeur « nom » de l'article n'est pas mis à jour quand il est modifié dans la zone de liste.

Quelle est une bonne façon de faire cela? Disons que je veux seulement montrer tous les noms d'item avec itemtype B. Peut-il être fait en liaison wpf ou dois-je faire du code derrière?

Répondre

2

C'est une référence à la source de données, par ex. à une collection dans votre viewmodel si vous utilisez le modèle MVC. La chose étonnante est, que c'est si simple dans l'utilisation. La vue est mise à jour et possède sa propre gestion d'actualisation. Je vais faire un petit exemple:

En WPF:

<ListBox ItemsSource={Binding Path=MySource} ItemTemplate="{StaticResource myItemTemplate}" /> 

La logique de code:

public class Item 
{ 
    public string Name { get; set; } 
    public string Type { get; set; } 
} 

public class MyViewModel 
{ 
    public ObservableCollection<Item> MySource { get; set; } 

    public MyViewModel() 
    { 
     this.MySource = new ObservableCollection<Item>(); 
     this.MySource.Add(new Item() { Name = "Item4", Type = "C" }); 
     this.MySource.Add(new Item() { Name = "Item1", Type = "A" }); 
     this.MySource.Add(new Item() { Name = "Item2", Type = "B" }); 
     this.MySource.Add(new Item() { Name = "Item3", Type = "A" }); 

     // get the viewsource 

     ListCollectionView view = (ListCollectionView)CollectionViewSource 
      .GetDefaultView(this.MySource); 

     // first of all sort by type ascending, and then by name descending 
     view.SortDescriptions.Add(new SortDescription("Type", ListSortDirection.Ascending)); 
     view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending)); 

     // now i like to group the items by type 
     view.GroupDescriptions.Add(new PropertyGroupDescription("Type")); 

     // and finally i want to filter all items, which are of type C 
     // this is done with a Predicate<object>. True means, the item will 
     // be shown, false means not 
     view.Filter = (item) => 
      { 
       Item i = item as Item; 
       if (i.Type != "C") 
        return true; 
       else 
        return false; 
      }; 


     // if you need a refreshment of the view, because of some items were not updated 
     view.Refresh(); 

     // if you want to edit a single item or more items and dont want to refresh, 
     // until all your edits are done you can use the Edit pattern of the view 

     Item itemToEdit = this.MySource.First(); 
     view.EditItem(itemToEdit); 
     itemToEdit.Name = "Wonderfull item"; 

     view.CommitEdit(); 

     // of course Refresh/Edit only makes sense in methods/callbacks/setters not 
     // in this constructor 
    } 

} 

Intéressant est que ce modèle affecte directement la zone de liste dans l'IUG. Si vous ajoutez le groupage/tri, cela affectera le comportement d'affichage de la listbox, même si la source d'éléments n'est liée qu'au viewmodel.

+0

Merci pour l'explication détaillée. Alors, comment définir ma source de données actuelle en tant que collection observable? Donc, selon votre explication, je filtre cette collection. Dois-je lier la collection à ma liste déroulante dans le code ou dans le xaml? – internetmw

+0

Cela a été extrêmement utile, merci !! –

2

Le problème avec la liaison dans ce cas, c'est que c'est seulement un ensemble une fois. Donc, si vous le liez, les sources sont synchronisées. Vous pouvez utiliser un convertisseur pour la liaison, qui filtre les éléments que vous n'aimez pas lier. Une autre façon serait d'utiliser CollectionViewSource de WPF.

Vous pouvez ajouter des groupements/tri et un filtre à un objet CollectionViewSource sur tout type de ItemsSource. Utilisez le ListCollectionView par exemple.

ListCollectionView view = 
    (ListCollectionView)CollectionViewSource.GetDefaultView(yourEnumerableSource); 
+0

Ainsi, 'yourEnumerableSource' fait-il référence à la liste ou à la source de données? Et c'est la vue mise à jour quand une modification est apportée à la source de données? – internetmw

+0

voir le deuxième article – JanW

Questions connexes