WPF TreeView Очистить выбор - PullRequest
       20

WPF TreeView Очистить выбор

8 голосов
/ 24 марта 2009

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

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

Ответы [ 9 ]

11 голосов
/ 10 сентября 2009

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

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;
                }
            }
    }
}
8 голосов
/ 24 марта 2009

Не уверен, что вы подразумеваете под 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;
3 голосов
/ 24 марта 2009

Найдите выбранный пункт и установите значение:

private void Button_Click(object sender, RoutedEventArgs e)
{
  TreeViewItem tvi = treeviewExample.SelectedItem as TreeViewItem;
  if (tvi != null)
  {
    tvi.IsSelected = false;
  }
}
2 голосов
/ 05 августа 2010

Это прекрасно работает как метод расширения, поэтому вы можете вызвать

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 голос
/ 24 июля 2017
TreeViewItem tvi = tvMain.ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;

if (tvi != null) { tvi.IsSelected = true; tvi.IsSelected = false; }
1 голос
/ 28 июня 2011

Мой опыт - держаться подальше от стандартных вызовов ItemContainerGenerator, потому что они не будут работать на узлах на глубине, превышающей n + 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 голосов
/ 27 апреля 2016

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

Быстрое и грязное решение

tree.ItemsSource = null;

tree.ItemsSource = yourSource;
0 голосов
/ 12 сентября 2013

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

Полное объяснение можно найти на 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 и сохраняете источник события в атрибуте Tag в TreeView. Затем, когда вам нужно очистить его, вы можете получить доступ к атрибуту Tag на вашем элементе управления и установить значение IsSelected в False. Это работает для меня с 2 уровнями вложенных детей. Надеюсь, это сработает для вас.

Ради настойчивости:

Объявление TreeView

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

Обработчик событий

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

Очистить логику выбора

if (myTreeView.SelectedItem != null)
{
    TreeViewItem selectedTVI = myTreeView.Tag as TreeViewItem;
    // add your code here mine was selectedTVI.IsSelected = false;
}
0 голосов
/ 03 декабря 2009

Пока что это работает, но я просто вставил это 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;
        }
     }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...