Как программно выбрать элемент в WPF TreeView? - PullRequest
45 голосов
/ 05 января 2009

Как можно программно выбрать элемент в WPF TreeView? Модель ItemsControl, кажется, предотвращает это.

Ответы [ 14 ]

38 голосов
/ 02 ноября 2010

Для тех, кто все еще ищет правильное решение этой проблемы, вот один ниже. Я нашел это в комментариях к статье проекта кода «Выбор WPF TreeView» http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx от DaWanderer. Он был опубликован Kenrae 25 ноября 2008 года. Это отлично сработало для меня. Спасибо Кенре!

Вот его пост:

Вместо того, чтобы ходить по дереву, используйте свой собственный объект данных со свойством IsSelected (и я тоже рекомендую свойство IsExpanded). Определите стиль для TreeViewItems дерева, используя свойство ItemContainerStyle в TreeView, которое связывает эти свойства из TreeViewItem с вашими объектами данных. Примерно так:

<Style x:Key="LibraryTreeViewItemStyle"
               TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded"
                        Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected"
                        Value="{Binding IsSelected, Mode=TwoWay}" />
            <Setter Property="FontWeight"
                        Value="Normal" />
            <Style.Triggers>
                  <Trigger Property="IsSelected"
                              Value="True">
                        <Setter Property="FontWeight"
                                    Value="Bold" />
                  </Trigger>
            </Style.Triggers>
      </Style>

<TreeView ItemsSource="{Binding Path=YourCollection}"
               ItemContainerStyle="{StaticResource LibraryTreeViewItemStyle}"
               ItemTemplate={StaticResource YourHierarchicalDataTemplate}/>
23 голосов
/ 05 января 2009

Вам нужно получить TreeViewItem, а затем установить IsSelected на true.

23 голосов
/ 05 января 2009

Это настоящая боль по какой-то странной причине: вы должны использовать ContainerFromItem, чтобы получить контейнер, а затем вызвать метод select.

//  selectedItemObject is not a TreeViewItem, but an item from the collection that 
//  populated the TreeView.

var tvi = treeView.ItemContainerGenerator.ContainerFromItem(selectedItemObject) 
          as TreeViewItem;

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

Когда-то была запись в блоге о том, как это сделать здесь , но ссылка сейчас не работает.

7 голосов
/ 17 сентября 2015

Мне удалось с этим кодом:

public static TreeViewItem FindTviFromObjectRecursive(ItemsControl ic, object o) {
  //Search for the object model in first level children (recursively)
  TreeViewItem tvi = ic.ItemContainerGenerator.ContainerFromItem(o) as TreeViewItem;
  if (tvi != null) return tvi;
  //Loop through user object models
  foreach (object i in ic.Items) {
    //Get the TreeViewItem associated with the iterated object model
    TreeViewItem tvi2 = ic.ItemContainerGenerator.ContainerFromItem(i) as TreeViewItem;
    tvi = FindTviFromObjectRecursive(tvi2, o);
    if (tvi != null) return tvi;
  }
  return null;
}

Использование:

var tvi = FindTviFromObjectRecursive(TheTreeView, TheModel);
if (tvi != null) tvi.IsSelected = true;
5 голосов
/ 09 августа 2010

Это не так просто, как кажется, ссылка, предоставленная Стивеном, имеет решение, опубликованное в 2008 году, которое может все еще работать, но не заботится о Virtualized TreeViews. Более того, многие другие проблемы упоминаются в комментариях к этой статье. Без обид, но я тоже застрял с той же проблемой и не могу найти идеального решения. Вот ссылки на некоторые статьи / посты, которые мне очень помогли -

Как я могу развернуть элементы в TreeView? - Часть III: http://bea.stollnitz.com/blog/?p=59

Программный выбор элемента в TreeView: http://blog.quantumbitdesigns.com/2008/07/22/programmatically-selecting-an-item-in-a-treeview/#respond

TreeView, TreeViewItem и IsSelected: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7e368b93-f509-4cd6-88e7-561e8d3246ae/

2 голосов
/ 08 марта 2016

Я написал метод расширения:

using System.Windows.Controls;

namespace Extensions
{
    public static class TreeViewEx
    {
        /// <summary>
        /// Select specified item in a TreeView
        /// </summary>
        public static void SelectItem(this TreeView treeView, object item)
        {
            var tvItem = treeView.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
            if (tvItem != null)
            {
                tvItem.IsSelected = true;
            }
        }
    }
}

Который я могу использовать так:

if (_items.Count > 0)
    _treeView.SelectItem(_items[0]);
1 голос
/ 06 сентября 2013

Если вы хотите выбрать элемент, находящийся у детей, вы можете сделать это для пользователя.

public bool Select(TreeViewItem item, object select) // recursive function to set item selection in treeview
{
    if (item == null)
        return false;
    TreeViewItem child = item.ItemContainerGenerator.ContainerFromItem(select) as TreeViewItem;
    if (child != null)
    {
        child.IsSelected = true;
        return true;
    }
    foreach (object c in item.Items)
    {
        bool result = Select(item.ItemContainerGenerator.ContainerFromItem(c) as TreeViewItem, select);
        if (result == true)
            return true;
    }
    return false;
}
0 голосов
/ 19 ноября 2018

Предложенный ответ не работает. Ответ @ fandisusanto, вероятно, работает, но его можно упростить. Это самый простой ответ, который я могу придумать:

    private static void DeselectTreeViewItem(IEnumerable<TreeViewItem> treeViewItems)
    {
        foreach (var treeViewItem in treeViewItems)
        {
            if (treeViewItem.IsSelected)
            {
                treeViewItem.IsSelected = false;
                return;
            }

            DeselectTreeViewItem(treeViewItem.Items.Cast<TreeViewItem>());
        }
    }

Использование:

    private void ClearSelectedItem()
    {
        if (AssetTreeView.SelectedItem != null)
        {
            DeselectTreeViewItem(AssetTreeView.Items.Cast<TreeViewItem>());
        }
    }
0 голосов
/ 24 сентября 2018

Я думаю, что это самое простое решение:

private void MouseDownEventProcessing(TreeNodeMouseClickEventArgs e)
{
    tvEmployeeDirectory.SelectedNode = e.Node;
}
0 голосов
/ 27 октября 2016

Вы можете сделать это с помощью кода позади

if (TreeView1.Items.Count > 0)
        (TreeView1.Items[0] as TreeViewItem).IsSelected = true;
...