2008-12-17 8 views
6

Tell me it ain't so.Wo ist IsSynchronizedWithCurrentItem -Eigenschaft (oder gleichwertig) für eine TreeView?

Ich habe eine typische Windows/Datei Explorer wie Setup.

  • Linke Seite Ich habe eine TreeView alle gebundenen Datenknoten in einer Hierachie
  • Rechte Seite Ich habe eine Listview zeigt Node.Properties

Listview hat eine IsSynchronizedWithCurrentItem Eigenschaft zeigt, die rockt. z.B. Wenn ich eine andere ListView hätte, die eine Liste von Knoten zeigt, und beide ListViews haben diese Eigenschaft auf true gesetzt. Durch Ändern der Auswahl des Knotens in NodesListView wird die Eigenschaftenliste automatisch aktualisiert.

Jetzt brauche ich das gleiche mit einem NodesTreeView und einer PropertiesListView ... und scheint wie TreeView keine solche Eigenschaft hat.

Gibt es eine "WPF-Art" Lösung für dieses Problem? Oder muss ich das NodeSelectionChanged-Ereignis des Baums behandeln und das ListView über Code aktualisieren.

Antwort

0

Meine Lösung zu diesem entpuppte sich als ziemlich winzig .. weiß nicht, ob es IsSynchronizedWithCurrentItem entspricht. ListView wird wie erwartet aktualisiert.

// the XAML 
<TreeView DockPanel.Dock="Left" x:Name="tvwNodes" ItemsSource="{Binding}" SelectedItemChanged="OnNewNodeSelected"/> 
<ListView x:Name="lvwProperties" ItemsSource="{Binding Path=Properties}" 

// the code-behind 
private void OnNewNodeSelected(object sender, RoutedPropertyChangedEventArgs<object> e) 
{ 
    lvwProperties.DataContext = tvwNodes.SelectedItem; // this returns the selected Node obj 
} 
3

Warum genau ist es nicht die Eigenschaft implementieren, weiß ich nicht, aber ich habe unten einen Vorschlag.

Ihr Code oben funktioniert, aber es ist nicht was die IsSynchronizedWithCurrentItem Eigenschaft tut. Jedes ItemsControl bindet an die ICollectionView der ItemsSource-Eigenschaft. Um diese ICollectionView zu erhalten, können wir CollectionViewSource.GetDefaultCollectionView (Objekt o) aufrufen. Je nach Art des Objekts o erhalten Sie eine andere konkrete Implementierung der ICollectionView-Schnittstelle. CollectionView und ListCollectionView sind zwei konkrete Klassen, die Ihnen in den Sinn kommen.

Die ICollectionView-Schnittstelle enthält ein Member namens CurrentItem. Was IsSynchronizedWithCurrentItem tut, ist Folgendes: Wann immer ein Element auf ItemsControl geklickt wird, wird das CurrentItem für die Sammlungsansicht festgelegt. Die ICollectionView verfügt außerdem über zwei Ereignisse: CurrentItemChanging und CurrentItemChanged. Wenn die IsSynchronizedWithCurrentItem-Eigenschaft festgelegt ist, aktualisiert das ItemsControl das SelectedItem basierend auf dem CurrentItem der ICollectionView. Macht Sinn?

In Master/Detail-WPF-Szenarien, wir sind einfach die Bindung an ICollectionViews und ihre CurrentItem (die CurrentItem Syntax ist so etwas wie {Binding Artikel/Name}, wobei Name der Name-Eigenschaft auf der CurrentItem Sammlung ist.

So ., obwohl der Code für Ihre Zwecke arbeitet, tut es nicht, was das Objekt tut, um zu tun, was die Eigenschaft der Fall ist, müssen Sie folgendes tun:

  1. Wenn ein Element ausgewählt ist, müssen Sie, um herauszufinden, welche Sammlung, zu der es gehört .. Wie machen wir das? Ich glaube, das ist der Grund, warum TreeView es nicht implementiert.Das ausgewählte Element wird in einer TreeViewIte angezeigt m. Der DataContext ist das Objekt selbst, aber was ist die Elternsammlung? Ich schätze, um es zu bekommen, könntest du es entweder in etwas hashmap zwischenspeichern (albern, aber es wird funktionieren) oder du kannst den logischen Baum hinaufgehen und das TreeViewItem-Elternelement bekommen, das zufälligerweise ein ItemsControl ist. Die ItemsSource-Eigenschaft wird Ihre Sammlung sein.
  2. Holen Sie sich die ICollectionView für diese Sammlung.
  3. benötigen, dass ICollectionView in eine Collection zu werfen
  4. Anruf SetCurrent (.., ..) auf der Collection Instanz

Nun, alles, was das (ICollectionView nicht CurrentItem Setter nicht implementiert) gebunden ist, Das CurrentItem von ICollectionView wird aktualisiert.

Dies wurde länger als ich erwartet hatte. Lassen Sie mich wissen, wenn weitere Erläuterungen erforderlich sind.

6

Eine wirklich einfache Lösung ist, Ihre "Details" UI-Elemente an die SelectedValue-Eigenschaft der TreeView zu binden. Zum Beispiel sah, wenn Ihr TreeView wie folgt aus:

<TreeView Name="CategoryName" ItemsSource="{Binding Source={StaticResource A_Collection}, Path=RootItems}" /> 

Dann könnten Sie Details UI-Elemente binden (wie ein Textfeld) mit:

<TextBox Text="{Binding ElementName=CategoryTreeView, Path=SelectedValue.Name}"/> 

Möchten Sie das Textfeld führen gebunden zu sein Name-Eigenschaft die aktuell in der TreeView ausgewählten Objekte.

Wenn Sie viele UI-Elemente als Details für das ausgewählte TreeView-Element binden möchten, sollten Sie einen DataContext für das Element einrichten, das alle Detailsteuerelemente (DockPanel/Grid/StackPanel usw.) enthält.

3
<ListView Name="listView1" 
    ItemsSource="{Binding Path=SelectedItem.Modules, 
          ElementName=treeView1, Mode=OneWay}" 
    IsSynchronizedWithCurrentItem="True"> 

Wo „.Modules“ ist die Sammlung von untergeordneten Elemente aus der gewählten treeview Element, das Sie anzeigen möchten. Machen Sie sich keine Sorgen darüber, das Ereignis "SelectedItemChanged" in der Baumstruktur zu verkabeln.

+0

Warum wird diese Antwort nicht akzeptiert? – Dabblernl

Verwandte Themen