2008-12-17 10 views
6

Tell me it ain't so.¿Dónde está la propiedad IsSynchronizedWithCurrentItem (o equivalente) para un TreeView?

Tengo una típica ventana/explorador de archivos como configuración.

  • lado izquierdo tengo un TreeView todos los datos ligados que muestran los nodos de una jerarquía
  • lado derecho Tengo un ListView mostrando Node.Properties

ListView tiene una propiedad IsSynchronizedWithCurrentItem, que se balancea. p.ej. Si tuviera otro ListView que muestra una lista de nodos y ambos listViews tienen esta propiedad establecida en verdadero. Cambiar la selección del nodo en NodesListView actualizará automáticamente el PropertiesListView.

Ahora necesito lo mismo con un NodesTreeView y un PropertiesListView ... y parece que TreeView no tiene esa propiedad.

¿Hay una solución más 'a la manera WPF' a este problema? O tengo que manejar el evento NodeSelectionChanged del Árbol y actualizar ListView mediante el código.

Respuesta

0

Mi solución a esto resultó ser bastante pequeña ... no sé si es equivalente a IsSynchronizedWithCurrentItem. ListView se actualiza como se esperaba.

// 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

¿Por qué exactamente no implementa la propiedad, no sé, pero tengo una sugerencia a continuación.

Su código anterior funcionará, sin embargo, no es lo que hace la propiedad IsSynchronizedWithCurrentItem. Any ItemsControl se une a la propiedad ICollectionView de ItemsSource. Para obtener ese ICollectionView, podemos llamar a CollectionViewSource.GetDefaultCollectionView (objeto o). Dependiendo del tipo de objeto o, se obtiene una implementación concreta diferente de la interfaz ICollectionView. CollectionView y ListCollectionView son dos clases concretas que vienen a la mente.

La interfaz ICollectionView contiene un miembro llamado CurrentItem. Lo que IsSynchronizedWithCurrentItem hace es: cada vez que se hace clic en un elemento en ItemsControl, establece el elemento actual para la vista de colección. ICollectionView también tiene dos eventos: CurrentItemChanging y CurrentItemChanged. Cuando se establece la propiedad IsSynchronizedWithCurrentItem, ItemsControl actualizará el SelectedItem en función de lo que es CurrentItem de ICollectionView. ¿Tiene sentido?

En maestro/detalle escenarios WPF, simplemente son vinculantes para ICollectionViews y su CurrentItem (la sintaxis CurrentItem es algo así como {Elementos de unión/Name}, donde nombre es la propiedad Name en CurrentItem de la colección.

Así . a pesar de que el código funciona para sus propósitos, que no hace lo que hace que la propiedad para hacer lo que hace la propiedad, que tiene que hacer lo siguiente:

  1. Cuando se selecciona un elemento, es necesario averiguar qué colección a la que pertenece. ¿Cómo hacemos esto? Creo que esta es la razón por TreeView no lo implementa. El elemento seleccionado se muestra en un TreeViewIte metro. El DataContext es el objeto en sí, pero ¿cuál es la colección principal? Supongo que para obtenerlo, puedes guardarlo en algún hashmap (tonto, pero funcionará) o puedes subir al árbol lógico y obtener el elemento principal TreeViewItem que resulta ser un ItemsControl. La propiedad ItemsSource será su colección.
  2. Obtenga ICollectionView para esa colección.
  3. necesario que convierta en un ICollectionView que CollectionView (ICollectionView no implementa CurrentItem colocador)
  4. setCurrent de llamadas (.., ..) en la instancia CollectionView

Ahora, todo lo que está ligado a ese CurrentItem de ICollectionView se actualizará.

Esto se hizo más largo de lo que esperaba. Avíseme si es necesaria alguna otra aclaración.

6

Una solución realmente simple es unir sus elementos de IU de "detalles" a la propiedad SelectedValue de TreeView. Por ejemplo, si su TreeView se veía así:

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

Posteriormente, se podría unir elementos de datos de interfaz de usuario (como un cuadro de texto) usando:

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

haría que el cuadro de texto para obligarse a nombre de la propiedad de los elementos actualmente seleccionados en TreeView.

Si desea vincular muchos elementos de la interfaz de usuario como detalles para el elemento TreeView seleccionado, considere configurar un DataContext en el elemento que contiene todos los controles de detalles (DockPanel/Grid/StackPanel, etc.).

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

Donde ".Modules" es la colección de elementos secundarios fuera de la vista de árbol seleccionada elemento que desea visualizar. No se preocupe por cablear el evento "SelectedItemChanged" en la vista de árbol.

+0

¿Por qué no se acepta esta respuesta? – Dabblernl

Cuestiones relacionadas