2013-04-18 12 views
7

Ich habe eine Baumansicht erstellt, die Verzeichnisse und Dateien auf meiner Festplatte modelliert. Jedes treeviewItem hat ein Kontrollkästchen, das an eine isSelected-Eigenschaft gebunden ist. Was ich erreichen möchte, ist für jeden Elternknoten die Anzahl der ausgewählten Dateien auf der Gesamtzahl der Dateien anzuzeigen (10/12 10 Dateien auf insgesamt 12 ausgewählt).Wie filtern Sie eine Sammlung, wenn Sie sie an ItemsSource binden?

Gibt es eine Möglichkeit eine Bindung mit dem zu tun, wo Eigentum ist ...?

<ContentPresenter Content="{Binding MyItems.Count where MyItems.IsSelected, Mode=OneTime}" 
        Margin="2,0" /> 
+1

Sind Sie mit MVVM? – DHN

+1

In der Tat bin ich DHN. –

+1

Können Sie Ihre Viewmodels oder die Klassen veröffentlichen, die wegen der Code hinter dem TreeView – Jehof

Antwort

11

Es gibt keine Möglichkeit, direkt die Sammlung in der Bindung zu filtern. WPF ermöglicht jedoch das Filtern (und Sortieren und Gruppieren) von Sammlungen mit CollectionViewSource.

Ein Ansatz wäre, eine CollectionViewSource in den Ressourcen Ihres ItemTemplate zu definieren, die die ItemsSource filtert eine die Anzahl der Elemente erhalten, die den Filter durch Bindung an die Count-Eigenschaft dieses CollectionViewSource passieren. Sie müssen jedoch Ihren Filter in Codebehind definieren. Würde etwa so aussehen:

<TreeView x:Name="Tree" ItemsSource="{Binding Items}"> 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate ItemsSource="{Binding ChildItems}"> 
      <HierarchicalDataTemplate.Resources> 
       <CollectionViewSource x:Key="FilteredItems" 
             Source="{Binding ChildItems}" 
             Filter="FilteredItems_OnFilter" /> 
      </HierarchicalDataTemplate.Resources> 
      <TextBlock> 
       <TextBlock.Text> 
        <MultiBinding StringFormat="{} {0} of {1} selected"> 
         <Binding Path="Count" Source="{StaticResource FilteredItems}" /> 
         <Binding Path="ItemsSource.Count" ElementName="Tree" /> 
        </MultiBinding> 
       </TextBlock.Text> 
      </TextBlock> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

Und in dem Code-Behind:

private void FilteredItems_OnFilter(object sender, FilterEventArgs e) 
{ 
    var item = sender as Item; 
    e.Accepted = item.IsSelected; 
} 

Ich habe es nicht getestet, aber es sollte in der Regel arbeiten. Man weiß nie, mit WPF, obwohl ...

+0

Hinunter-Voting gebunden sind Teil –

+1

Ich glaube nicht eine Notwendigkeit, Unit-Test gibt es dieses ... – Marc

+0

Was? Keine Notwendigkeit, diese Einheit zu testen? Dann, wie überprüfen Sie, dass diese Funktionalität funktioniert? Automatisierte UI-Tests? Es ist das Vorrecht eines ViewModels, die aktuelle Auswahl zu enthalten, nicht Views. –

-9

ich persönlich den folgenden Rahmen http://logofx.codeplex.com/ verwenden, die alle Ihre Anforderungen zu erfüllen scheint (verwenden LogoFX.Mini, wie es für Ihre Zwecke genug scheint). Verwenden WrappingCollection.WithSelection als Itemssource Verwenden SelectionCount als Wert, den Sie anzeigen möchten. Wenn Sie sich entschließen, das Framework nicht zu verwenden, sollten Sie das ausgewählte Ereignis durch ein dediziertes Verhalten abonnieren, eine dedizierte Abhängigkeitseigenschaft erstellen und jedes Mal aktualisieren, wenn sich die Auswahl ändert.

Und eine letzte Sache: Auf jeden Fall vermeiden, mit Code-Behind. Es bricht das ganze MVVM-Prinzip.

+4

-1 - * Vermeiden Sie auf jeden Fall Code-Behind. * - Komm schon, das ist einfach nicht wahr. Bei Bedarf können Sie den Code dahinter verwenden. Stellen Sie sich ein 'CustomControl' vor, das Sie ohne Code nicht implementieren können. Aber es gibt verschiedene andere Gründe, wenn Code dahinter die einfachste Lösung ist. Wenn Sie schreiben würden ** Versuchen Sie, wann immer Sie können, um die Verwendung von Code zu vermeiden. **, ich wäre bei Ihnen. – DHN

+0

+1 für DHN, ich betrachte mich als ziemlich MVVM Fundamentalist, aber das ist definitiv nicht wahr. Verhalten sind nichts anderes als Codebehind von BTW ... – Marc

+0

Ich unterscheide zwischen den Steuerelementen, die von dem UserControl abgeleitet werden (aka Ansichten) und denen, die von dem Steuerelement abgeleitet werden (aka benutzerdefinierte Steuerelemente). Wenn ich von Code-Behind spreche, beziehe ich mich nur auf den ersten. Und im Fall von Views MUSS der Code-behind vermieden werden. Wie testen Sie so etwas, wenn es auf Code-Behind basiert? Wenn das Feature, das Sie zu implementieren versuchen, reines visuelles Verhalten ist, entspricht es der Implementierung in einem Code-Behind (immer noch nicht erforderlich, da Sie es entweder in XAML ausführen oder an ein Verhalten delegieren können). wenn es etwas anderes ist, machst du es falsch –

Verwandte Themen