2009-03-24 7 views
7

Как очистить выбор TreeView в WPF TreeView? Я пробовал зацикливаться через TreeNodes и очистить имущество IsSelected, однако это свойство ReadOnly. Есть идеи?WPF TreeView Очистить выбор

TreeView использует привязку XML через объект XMLDataProvider.

ответ

8

Не уверен, что вы подразумеваете под TreeNodes.

Обычно вы бы иметь соответствующий IsSelected свойство на вашей модели представления, что Ваше мнение связывается:

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

Таким образом, вы бы просто Переберите элементы данных в вашей модели представления и установить IsSelected = false там.

Однако, похоже, что у вас нет такого имущества. В этом случае вам необходимо получить соответствующий TreeViewItem для каждого элемента данных. Информацию о том, как это сделать, можно найти в файле TreeView.ItemContainerGenerator. Что-то вроде:

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

Я отчаянно искал способ, чтобы выбрать первый индекс в TreeView. Я попробовал решение сверху (ContainerFromIndex), но он возвращает null. Любая помощь? – Shimmy

2

Найти выбранный элемент и установите значение:

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

я наткнулся на точно такие же проблемы и написал следующий код, который будет работать на любом TreeView, только с одной строкой вызов первой функции.

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

Ничего не сработало до этого. Отлично! Спасибо! – StinkyCat

0

Это, кажется, работает до сих пор, но я просто положил его, как 5 минут назад, так что используйте на свой страх и риск. В основном я хотел очистить выбор, когда пользователь нажимает на элемент управления дерева, но не на элемент дерева.

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

Игнорируйте мой код. Работает только на корневом уровне. Любые выбранные дочерние узлы не будут очищены. –

2

Это работает большой как метод Удлинитель так можно назвать

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

Это был мой опыт, чтобы держаться подальше от стандартного ItemContainerGenerator звонки, потому что они не смогут на узлах на глубине большей, чем п +1. Ниже приведена комбинация следующих методов расширения. Методы расширения ContainerFromItem поступают из блога MSDN, и для меня это имеет большое значение при работе с 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

Я работала в этой ситуации себя с пользовательской реализации Tree 'Список присмотревшись в течение длительного времени я, наконец, нашел решение, которое работало для меня.

Полное объяснение можно найти в http://social.msdn.microsoft.com/Forums/vstudio/en-US/36aca7f7-0b47-488b-8e16-840b86addfa3/getting-treeviewitem-for-the-selected-item-in-a-treeview

Основная идея заключается вы захватить TreeViewItem.Selected событие и сохранить источник события в атрибуте на вашем TreeView Tag. Затем, когда вам нужно его очистить, вы можете получить доступ к атрибуту Tag на свой элемент управления и установить значение IsSelected в значение False. Это работает для меня с 2 уровнями вложенных детей. Надеюсь, это сработает для вас.

Ради инерционности:

TreeView декларация

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

Event Handler

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

Clear логика выбора

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

Я просто наткнулся на такой же проблемой.

быстрый и грязный раствор

tree.ItemsSource = null; 

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

if (tvi != null) { tvi.IsSelected = true; tvi.IsSelected = false; } 
Смежные вопросы