2010-08-17 15 views
11

Ich verwende CollectionViewSource, um die in einer ListBox angezeigten Datensätze zu filtern. Das Xaml folgt.Wie erhält man Artikel von 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> 

Und hier ist mein Code-behing (bitte don t diese Code-behind dagegen, in der realen Anwendung Ich bin mit dem besten von MVVM für dieses Szenario).

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); 
     } 
    } 

FRAGE: Ich brauche Hilfe in der „SetSummary“ Methode zu schreiben, wobei ich die „Anfangszaehler“ bekommen und die „filteredCount“ von Collection Objekt.

Vielen Dank für Ihr Interesse.

Antwort

6

Die Ansicht "source collection" und "collection" implementieren beide IEnumerable, sodass Sie immer über sie iterieren und zählen können, wie viele darin enthalten sind. Aber ich würde das nur empfehlen, wenn Sie keinen Zugriff auf die tatsächliche Sammlung haben, die Sie als Quelle verwendet haben.

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

Nur ein Hinweis, dass der filteredCount die Zahl ist, wenn visbile Elemente keine Anzahl der Elemente, die herausgefiltert wurden, zählen. – apc

2

Wenn Sie MVVM ausführen, könnte Ihre VM eine Sammlungsansicht erstellen, anstatt dass eine in Ihrem Auftrag von der CollectionViewSource erstellt wird. Dann haben Sie die Kontrolle darüber, welche Art von CVS erstellt wird, so dass Sie eine ListCollectionViewSource erstellen können, die eine Count Eigenschaft hat. Es hängt wirklich von den Eigenschaften der Daten ab, die Sie filtern.

+0

Sorry ich konnte es nicht bekommen. Kannst du das bitte mit etwas Code erklären, indem du meinen Code in den Kontext nimmst. Vielen Dank. –

32

könnten Sie auch _viewSource.View.Cast<object>().Count() für die gefilterte Liste und _viewSource.View.SourceCollection.Cast<object>().Count() für das Original tun.

+0

Vielen Dank für die Klärung, wie Sie den gefilterten/sortierten Inhalt einer CollectionViewSource erhalten. Ich konnte das erste Element in der CollectionViewSource nicht bis zu Ihrem Kommentar abrufen: var firstItem = this.xViewInDescendingOrder.View.Cast () .ElementAt (0); – rfreytag

8

Ich denke, die bessere Lösung ist, wie immer, Linq!

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

... oder ...

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

... wenn Sie Typ zur Laufzeit der Artikel nicht wissen!

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

Beschreiben Sie eine bti, was Sie an Ihrem Beispiel zeigen –

+0

Durch diese können Sie gezählt Anzahl der Artikel Quelle z. B. 2, 3 – EeNiArT

Verwandte Themen