2011-01-19 15 views
6

WPF Treeview responde a + y - teclas para expandir y contraer nodos en el árbol. ¡Estupendo!¿Treeview usa enlaces de comando para expandir/contraer?

¿Existe algún comando al que pueda vincular los botones de mi barra de herramientas o los elementos del menú para realizar las mismas acciones en la vista de árbol? No veo nada relacionado con expandir/colapsar en las constantes de comando de stock.

Respuesta

5

El TreeView maneja la expansión de un TreeViewItem con el ratón por la unión ToggleButton.IsChecked-TreeViewItem.IsExpanded en el ControlTemplate y se ocupa de expansión con el teclado en una anulación TreeViewItem.OnKeyDown. Entonces, no, no usa comandos en su implementación.

Pero puede agregar sus propios comandos sin mucho esfuerzo. En este ejemplo, he añadido un comportamiento a un TreeView de forma que responda a los estándares Open y Close aplicación comandos:

<DockPanel> 
    <Menu DockPanel.Dock="Top"> 
     <MenuItem Header="Open" CommandTarget="{Binding ElementName=treeView1}" Command="Open"/> 
     <MenuItem Header="Close" CommandTarget="{Binding ElementName=treeView1}" Command="Close"/> 
    </Menu> 
    <TreeView> 
     <i:Interaction.Behaviors> 
      <local:TreeViewCommandsBehavior/> 
     </i:Interaction.Behaviors> 
     <TreeViewItem Header="Root"> 
      <TreeViewItem Header="Item1"> 
       <TreeViewItem Header="Subitem1"/> 
       <TreeViewItem Header="Subitem2"/> 
      </TreeViewItem> 
      <TreeViewItem Header="Item2"> 
       <TreeViewItem Header="Subitem3"/> 
       <TreeViewItem Header="Subitem4"/> 
      </TreeViewItem> 
     </TreeViewItem> 
    </TreeView> 
</DockPanel> 

y aquí es el comportamiento que hace que el trabajo:

public class TreeViewCommandsBehavior : Behavior<TreeView> 
{ 
    private TreeViewItem selectedTreeViewItem; 

    protected override void OnAttached() 
    { 
     AssociatedObject.AddHandler(TreeViewItem.SelectedEvent, new RoutedEventHandler(TreeViewItem_Selected)); 
     AssociatedObject.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, CommandExecuted)); 
     AssociatedObject.CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, CommandExecuted)); 
    } 

    private void TreeViewItem_Selected(object sender, RoutedEventArgs e) 
    { 
     selectedTreeViewItem = e.OriginalSource as TreeViewItem; 
    } 

    private void CommandExecuted(object sender, ExecutedRoutedEventArgs e) 
    { 
     bool expand = e.Command == ApplicationCommands.Open; 
     if (selectedTreeViewItem != null) 
      selectedTreeViewItem.IsExpanded = expand; 
    } 
} 

Si no está familiarizado con las conductas, primero agregar este espacio de nombres:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

y añadir la referencia correspondiente a su proje Connecticut.

+2

Tenga en cuenta que el ensamblado System.Windows.Interactivity no forma parte de la distribución de tiempo de ejecución de .NET 4.0; está disponible en los redistribuibles del Microsoft Expression Blend SDK. – dthorpe

+0

De alguna manera, ese hecho me había eludido, probablemente porque el nombre de la asamblea. A pesar de que crea una dependencia en un ensamblaje externo, el uso de comportamientos es una gran ventaja porque hace que la característica sea reutilizable sin involucrar ningún código subyacente. Gracias por señalar eso. –