2009-03-24 16 views
7

¿Cómo eliminaría la selección de TreeView dentro de un WPF TreeView? He intentado recorrer el TreeNodes y borrar la propiedad IsSelected, sin embargo, es una propiedad ReadOnly. ¿Algunas ideas?WPF TreeView Borrar selección

El TreeView utiliza el enlace XML a través del objeto XMLDataProvider.

Respuesta

8

No estoy seguro de lo que quiere decir con TreeNodes.

Normalmente, usted tendría un IsSelected propiedad correspondiente del modelo de su opinión de que la vista se une a:

<TreeView> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="TreeViewItem"> 
      <Setter Property="IsSelected" Value="{Binding IsSelected}"/> 
     </Style> 
    </TreeView.ItemContainerStyle> 
</TreeView> 

Por lo tanto, usted acaba de recorrer los elementos de datos en el modelo de vista y establecer IsSelected = false allí.

Sin embargo, parece que no tiene esa propiedad. Siendo ese el caso, debe obtener el correspondiente TreeViewItem para cada elemento de datos. Consulte la propiedad TreeView.ItemContainerGenerator para obtener información sobre cómo hacer esto. Algo así como:

var treeViewItem = _treeView.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem; 
treeViewItem.IsSelected = false; 
+1

estoy buscando desesperadamente una manera de seleccionar el primer índice de un TreeView. Probé la solución desde arriba (ContainerFromIndex) pero devuelve null. ¿Alguna ayuda? – Shimmy

2

Encuentra el elemento seleccionado y establecer el valor:

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    TreeViewItem tvi = treeviewExample.SelectedItem as TreeViewItem; 
    if (tvi != null) 
    { 
    tvi.IsSelected = false; 
    } 
} 
10

me encontré con exactamente los mismos problemas y escribió el siguiente código que funcionará en cualquier vista de árbol, con una única línea llamar a la primera función.

class TomWrightsUtils 
{ 
    public static void ClearTreeViewSelection(TreeView tv) 
    { 
     if (tv != null) 
      ClearTreeViewItemsControlSelection(tv.Items, tv.ItemContainerGenerator); 
    } 
    private static void ClearTreeViewItemsControlSelection(ItemCollection ic, ItemContainerGenerator icg) 
    { 
     if ((ic != null) && (icg != null)) 
      for (int i = 0; i < ic.Count; i++) 
      { 
       TreeViewItem tvi = icg.ContainerFromIndex(i) as TreeViewItem; 
       if (tvi != null) 
       { 
        ClearTreeViewItemsControlSelection(tvi.Items, tvi.ItemContainerGenerator); 
        tvi.IsSelected = false; 
       } 
      } 
    } 
} 
+1

Nada había funcionado hasta esto. ¡Perfecto! ¡Gracias! – StinkyCat

0

Esto parece funcionar hasta ahora, pero lo puse como hace 5 minutos, así que utilícelo bajo su propio riesgo. Básicamente, quería borrar la selección cuando el usuario hace clic dentro del control de árbol, pero no en un elemento de árbol.

void DestinationTree_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    TreeView tree = sender as TreeView; 
    DestinationClientViewModel selectedItem = tree.SelectedItem as DestinationClientViewModel; 

    if (selectedItem != null) 
    { 
     int selectedItemIndex = this.DestinationTree.Items.IndexOf(selectedItem); 

     if (selectedItemIndex > -1) 
     { 
      TreeViewItem tvi = this.DestinationTree.ItemContainerGenerator.ContainerFromIndex(selectedItemIndex) as TreeViewItem; 
      if (tvi != null) 
       tvi.IsSelected = false; 
     } 
    } 
} 
+0

Ignora mi código. Solo funciona en el nivel raíz. Cualquier nodo hijo seleccionado no se borrará. –

2

esto funciona muy bien como método de extensión para que pueda llamar

youTreeview.ClearSelection(); 

using System.Windows.Forms; 
using System.Windows.Controls; 

namespace YourAppNamespace 
{ 
    public static void ClearSelection(this TreeView input) 
    { 
    // this should be some container that you put in 
    // possibly the actual treeviewitem, not sure on that though 
    var selected = input.SelectedItem; 
    if (selected == null) 
     return; 

    // in my case this works perfectly 
    var tvi = input.ItemContainerGenerator.ContainerFromItem(selected) as TreeViewItem; 
    var tvi = input.ItemContainerGenerator.ContainerFromItem(selected) as TreeViewItem; 
    if (tvi == null) 
    { 
     // it must be a child, heres a hack fix 
     // my nodes are inherited from TreeViewItemViewModel by Josh Smith 
     var child = selected as WPF.Controls.TreeViewItemViewModel; 
     if (child == null) 
      return; 
     child.IsSelected = false; 

    } 
    else 
     tvi.IsSelected = false; 
    } 


} 
1

Ha sido mi experiencia que se mantenga alejado de la norma ItemContainerGenerator llama, ya que se producirá un error en los nodos a una profundidad mayor que n +1. Uso la combinación de los siguientes métodos de extensión a continuación. Los métodos de extensión ContainerFromItem provienen de un blog de MSDN y me ha funcionado cuando trato con TreeView.

public static void ClearSelection(this TreeView input) 
    { 
    var selected = input.SelectedItem; 

    if (selected == null) return; 

    var tvi = input.ContainerFromItem(selected) as TreeViewItem; 

    if (tvi == null) return; 

    tvi.IsSelected = false; 

    } 

    public static TreeViewItem ContainerFromItem(this TreeView treeView, object item) 
    { 
    TreeViewItem containerThatMightContainItem = (TreeViewItem)treeView.ItemContainerGenerator.ContainerFromItem(item); 
    if (containerThatMightContainItem != null) 
     return containerThatMightContainItem; 
    else 
     return ContainerFromItem(treeView.ItemContainerGenerator, treeView.Items, item); 
    } 

    private static TreeViewItem ContainerFromItem(ItemContainerGenerator parentItemContainerGenerator, ItemCollection itemCollection, object item) 
    { 
    foreach (object curChildItem in itemCollection) 
    { 
     TreeViewItem parentContainer = (TreeViewItem)parentItemContainerGenerator.ContainerFromItem(curChildItem); 
     if (parentContainer == null) 
      return null; 
     TreeViewItem containerThatMightContainItem = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(item); 
     if (containerThatMightContainItem != null) 
      return containerThatMightContainItem; 
     TreeViewItem recursionResult = ContainerFromItem(parentContainer.ItemContainerGenerator, parentContainer.Items, item); 
     if (recursionResult != null) 
      return recursionResult; 
    } 
    return null; 
    } 
0

yo estaba corriendo en esta situación a mí mismo con una lista personalizada de vista de árbol aplicación después de buscar durante mucho tiempo, finalmente he encontrado una solución que trabajó para mí.

La explicación completa se puede encontrar en http://social.msdn.microsoft.com/Forums/vstudio/en-US/36aca7f7-0b47-488b-8e16-840b86addfa3/getting-treeviewitem-for-the-selected-item-in-a-treeview

La idea básica es que capture el evento TreeViewItem.Selected y guardar la fuente del evento en el atributo Tag en su TreeView. Luego, cuando necesite borrarlo, puede acceder al atributo Tag en su control y establecer el valor IsSelected en False. Esto funciona para mí con 2 niveles de niños anidados. Espero que funcione para usted.

Por el amor de persistencia:

declaración TreeView

<TreeView Name="myTreeView" TreeViewItem.Selected="OnItemSelected" 
    ItemsSource="{Binding Source={StaticResource myHierarchicalData}}"/> 

Gestor de Eventos

private void OnItemSelected(object sender, RoutedEventArgs e) 
{ 
    myTreeView.Tag = e.OriginalSource; 
} 

lógica de selección Borrar

if (myTreeView.SelectedItem != null) 
{ 
    TreeViewItem selectedTVI = myTreeView.Tag as TreeViewItem; 
    // add your code here mine was selectedTVI.IsSelected = false; 
} 
0

me encontré con el mismo problema.

Una solución rápida y sucia

tree.ItemsSource = null; 

tree.ItemsSource = yourSource; 
0
TreeViewItem tvi = tvMain.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem; 

if (tvi != null) { tvi.IsSelected = true; tvi.IsSelected = false; }