2010-08-17 7 views
11

J'utilise CollectionViewSource pour filtrer les enregistrements affichés dans un ListBox. Le xaml suit.Comment obtenir les articles de CollectionViewSource?

<Window x:Class="WPFStarter.ListBoxItemsFilter.ListBoxFilterUsingCollectionViewSource" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     x:Name="userControl" 
     Title="ListBoxFilterUsingCollectionViewSource" Height="300" Width="300"> 
     <Window.Resources> 
     <CollectionViewSource Source="{Binding ElementName=userControl, Path=DataContext.Items}" 
           x:Key="cvs" Filter="CollectionViewSource_Filter"/> 
     </Window.Resources> 
    <StackPanel Orientation="Vertical"> 
     <TextBox x:Name="txtSearch" TextChanged="txtSearch_TextChanged"/> 
     <TextBlock x:Name="txtSummary" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Bottom" FontSize="8"></TextBlock> 
     <ListBox ItemsSource="{Binding Source={StaticResource cvs}}" DisplayMemberPath="First"/> 
    </StackPanel> 

</Window> 

Et voici mon code behing (s'il vous plaît ne t l'esprit de ce code-behind, dans l'application réelle je suis en utilisant le meilleur de MVVM pour ce scénario).

public partial class ListBoxFilterUsingCollectionViewSource : Window 
    { 
     private string _text=""; 
     private readonly CollectionViewSource _viewSource; 

     public ListBoxFilterUsingCollectionViewSource() 
     { 
      InitializeComponent(); 
      _viewSource = this.FindResource("cvs") as CollectionViewSource; 
     } 

     private void CollectionViewSource_Filter(object sender, FilterEventArgs e) 
     { 
      var character = e.Item as Character; 
      e.Accepted = character != null && character.First.ToLower().Contains(_text.ToLower()); 
     } 

     private void txtSearch_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      _text = txtSearch.Text; 
      _viewSource.View.Refresh(); 

      SetSummary(); 
     } 

     private void SetSummary() 
     {     
      var initialCount = 10; //HELP???? 
      var filteredCount = 10; //HELP???? 
      txtSummary.Text = String.Format("{0} of {1}", filteredCount, initialCount); 
     } 
    } 

QUESTION: je besoin d'aide par écrit la méthode "SetSummary", où je peux obtenir le "initialCount" et le "filteredCount" de l'objet CollectionViewSource.

Merci de votre intérêt.

Répondre

6

La collection source et collectionview implémente IEnumerable de sorte que vous pouvez toujours itérer sur eux et compter combien sont en eux. Mais je ne recommanderais de le faire que si vous n'avez pas accès à la collection que vous avez utilisée comme source.

private void SetSummary() 
{ 
    int initialCount = 0; 
    foreach(var item in _viewSource.View.SourceCollection) 
    { 
     initialCount++; 
    } 

    int filteredCount = 0; 
    foreach (var item in _viewSource.View) 
    { 
     filteredCount++; 
    } 
} 
+1

Juste une note que le fichier filteredCount est le nombre si les éléments visbile ne sont pas un compte des éléments qui ont été filtrés. – apc

2

Si vous utilisez MVVM, votre machine virtuelle peut créer une vue de collection plutôt qu'une création créée en votre nom par le CollectionViewSource. Ensuite, vous avez le contrôle sur le type de CVS créé, donc vous pouvez créer un ListCollectionViewSource, qui a une propriété Count. Cela dépend vraiment des propriétés des données que vous filtrez.

+0

Désolé je n'ai pas pu l'obtenir. Pouvez-vous s'il vous plaît expliquer avec du code en prenant mon code dans le contexte. Merci. –

32

Vous pouvez également faire _viewSource.View.Cast<object>().Count() pour la liste filtrée et _viewSource.View.SourceCollection.Cast<object>().Count() pour l'original.

+0

Merci d'avoir clarifié comment obtenir le contenu filtré/trié d'une CollectionViewSource. J'ai été incapable d'obtenir le premier élément dans CollectionViewSource jusqu'à votre commentaire: var firstItem = this.xViewInDescendingOrder.View.Cast () .ElementAt (0); – rfreytag

8

Je pense que la meilleure solution est, comme d'habitude, Linq!

_viewSource.View.Cast<[your_type]>().Count(); 

... ou ...

_viewSource.View.Cast<object>().Count(); 

... si vous ne connaissez pas le type à l'exécution des articles!

2
var count = DataGrid.ItemsSource.OfType<object>().Count(); 
+0

Décrivez un bti ce que vous montrez à votre exemple –

+0

Grâce à cela, vous pouvez obtenir nombre d'éléments comptés par exemple 2, 3 – EeNiArT

Questions connexes