简体   繁体   English

如何以编程方式选择 WPF TreeView 中的项目?

[英]How to programmatically select an item in a WPF TreeView?

How is it possible to programmatically select an item in a WPF TreeView ?如何以编程方式选择 WPF TreeView的项目? The ItemsControl model seems to prevent it. ItemsControl模型似乎阻止了它。

For those who are still looking for the right solution to this problem here is the one below.对于那些仍在寻找此问题的正确解决方案的人,这里是下面的一个。 I found this one in the comments to the Code Project article “WPF TreeView Selection” http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx by DaWanderer.我在 DaWanderer 对代码项目文章“WPF TreeView 选择” http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx的评论中发现了这一点。 It was posted by Kenrae on Nov 25 2008. This worked great for me.它由 Kenrae 于 2008 年 11 月 25 日发布。这对我很有用。 Thanks Kenrae!谢谢肯莱!

Here is his post:这是他的帖子:

Instead of walking the tree, have your own data object have the IsSelected property (and I recommend the IsExpanded property too).不要遍历树,而是让您自己的数据对象具有 IsSelected 属性(我也推荐 IsExpanded 属性)。 Define a style for the TreeViewItems of the tree using the ItemContainerStyle property on the TreeView that binds those properties from the TreeViewItem to your data objects.使用 TreeView 上的 ItemContainerStyle 属性为树的 TreeViewItems 定义样式,该属性将 TreeViewItem 中的这些属性绑定到您的数据对象。 Something like this:像这样的东西:

<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}/>

It's a real pain for some strange reason, you have to use ContainerFromItem to get the container, then invoke the select method.由于某些奇怪的原因,这真的很痛苦,您必须使用 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;
}

There once was a blog entry on how to do it here , but the link is dead now.曾经有一篇关于如何在此处执行操作的博客条目,但该链接现在已失效。

您需要获取TreeViewItem ,然后将IsSelected设置为true

I've succeeded with this code:我已成功使用此代码:

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;
}

Usage:用法:

var tvi = FindTviFromObjectRecursive(TheTreeView, TheModel);
if (tvi != null) tvi.IsSelected = true;

This is not as simple as it looks, the link provided by Steven has a solution posted in 2008, which may still works but doesn't take care of Virtualized TreeViews.这并不像看起来那么简单,Steven 提供的链接在 2008 年发布了一个解决方案,该解决方案可能仍然有效,但不会处理 Virtualized TreeViews。 Moreover many other problems are mentioned in comments of that article.此外,该文章的评论中还提到了许多其他问题。 No offences, but I am also stuck with same problem and can't find a perfect solution.没有冒犯,但我也遇到了同样的问题,找不到完美的解决方案。 Here are the links to some of the articles/posts which helped me a lot-以下是一些对我有很大帮助的文章/帖子的链接-

How can I expand items in a TreeView?如何在 TreeView 中展开项目? – Part III: http://bea.stollnitz.com/blog/?p=59 – 第三部分: http : //bea.stollnitz.com/blog/?p=59

Programmatically Selecting an Item in a TreeView: http://blog.quantumbitdesigns.com/2008/07/22/programmatically-selecting-an-item-in-a-treeview/#respond以编程方式在 TreeView 中选择项目: http : //blog.quantumbitdesigns.com/2008/07/22/programmatically-selecting-an-item-in-a-treeview/#respond

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

I wrote an extension method:我写了一个扩展方法:

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;
            }
        }
    }
}

Which I can use like this:我可以这样使用:

if (_items.Count > 0)
    _treeView.SelectItem(_items[0]);

If you want to select item located withing children of child you can user recursion to do that.如果您想选择位于孩子的孩子的项目,您可以使用递归来做到这一点。

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;
}

Just thought I would chime in with the solution I went with, in case this can help anyone.只是想我会加入我采用的解决方案,以防这可以帮助任何人。 Note that the best way to do this is using a bound property like 'IsSelected' as per kuninl's answer, but in my case it was a legacy application that did not follow MVVM, so I ended up with the below.请注意,执行此操作的最佳方法是根据 kuninl 的回答使用“IsSelected”之类的绑定属性,但在我的情况下,它是一个未遵循 MVVM 的遗留应用程序,因此我最终得到了以下内容。

private void ChangeSessionSelection()
{
    foreach (SessionContainer item in this.treeActiveSessions.Items)
    {
        var treeviewItem = this.treeActiveSessions.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;

        if (item.Session == this.selectedSession.Session)
        {
            treeviewItem.IsSelected = true;
            treeviewItem.IsExpanded = true;
        }
        else
        {
            treeviewItem.IsSelected = false;
            treeviewItem.IsExpanded = false;
        }
    }            
}

What this does is select and expand the treeview item in the UI that represents the selected dataitem in the code behind.这样做是在 UI 中选择并展开表示所选数据项的树视图项。 The purpose of this was to have the selection change in the treeview when the users selection changed in an items control in the same window.这样做的目的是当用户选择在同一窗口中的项目控件中更改时,树视图中的选择更改。

I have created a method VisualTreeExt.GetDescendants<T> that returns an enumerable collection of elements that match the specified type:我创建了一个方法VisualTreeExt.GetDescendants<T> ,它返回与指定类型匹配的元素的可枚举集合:

public static class VisualTreeExt
{
  public static IEnumerable<T> GetDescendants<T>(DependencyObject parent) where T : DependencyObject
  {
    var count = VisualTreeHelper.GetChildrenCount(parent);
    for (var i = 0; i < count; ++i)
    {
       // Obtain the child
       var child = VisualTreeHelper.GetChild(parent, i);
       if (child is T)
         yield return (T)child;

       // Return all the descendant children
       foreach (var subItem in GetDescendants<T>(child))
         yield return subItem;
    }
  }
}

When you ask for VisualTreeHelperExt.GetDescendants<TreeViewItem>(MyAmazingTreeView) you'll get all the TreeViewItem childs.当您要求VisualTreeHelperExt.GetDescendants<TreeViewItem>(MyAmazingTreeView)您将获得所有TreeViewItem You can select a particular value using the following piece of code:您可以使用以下代码选择特定值:

var treeViewItem = VisualTreeExt.GetDescendants<TreeViewItem>(MyTreeView).FirstOrDefault(tvi => tvi.DataContext == newValue);
if (treeViewItem != null)
  treeViewItem.IsSelected = true;

It's a bit of a dirty solution (and probably not the most efficient) and won't work if you're using a virtualized TreeView, because it depends on the existance of the actual visual elements.这是一个有点肮脏的解决方案(并且可能不是最有效的)并且如果您使用虚拟化的 TreeView 将不起作用,因为它取决于实际视觉元素的存在。 But it works for my situation...但它适用于我的情况......

Yeah.. I know many years past since the question was asked but.. still no quick solution to this problem.. and So:是的..我知道这个问题已经过去很多年了但是..仍然没有快速解决这个问题..所以:

The following will do what the OP asked for.以下将执行 OP 要求的操作。

What I basically done is reading all the answers in this page and following all the relevant links to create a once and for all solution to this irritating problem.我基本上所做的是阅读此页面中的所有答案,并按照所有相关链接为这个恼人的问题创建一个一劳永逸的解决方案。

Benefits:好处:

  • It support Virtualizing TreeView as well.它也支持虚拟化 TreeView。
  • It using the behavior technique, so XAML is way easy.它使用行为技术,因此 XAML 很容易。
  • Adds a dependancy-property to allow binding to the selected TreeView Item.添加一个依赖属性以允许绑定到选定的 TreeView 项。

This part is the only code you need to copy, the other parts are just to help complete an example.这部分是你唯一需要复制的代码,其他部分只是帮助完成一个例子。

public static class TreeViewSelectedItemExBehavior
{
    private static List<TreeView> isRegisteredToSelectionChanged = new List<TreeView>();

    public static readonly DependencyProperty SelectedItemExProperty =
        DependencyProperty.RegisterAttached("SelectedItemEx",
            typeof(object),
            typeof(TreeViewSelectedItemExBehavior),
            new FrameworkPropertyMetadata(new object(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedItemExChanged, null));

    #region SelectedItemEx

    public static object GetSelectedItemEx(TreeView target)
    {
        return target.GetValue(SelectedItemExProperty);
    }

    public static void SetSelectedItemEx(TreeView target, object value)
    {
        target.SetValue(SelectedItemExProperty, value);
        var treeViewItemToSelect = GetTreeViewItem(target, value);
        if (treeViewItemToSelect == null)
        {
            if (target.SelectedItem == null)
                return;
            var treeViewItemToUnSelect = GetTreeViewItem(target, target.SelectedItem);
            treeViewItemToUnSelect.IsSelected = false;
        }
        else
            treeViewItemToSelect.IsSelected = true;
    }

    public static void OnSelectedItemExChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        var treeView = depObj as TreeView;
        if (treeView == null)
            return;
        if (!isRegisteredToSelectionChanged.Contains(treeView))
        {
            treeView.SelectedItemChanged += TreeView_SelectedItemChanged;
            isRegisteredToSelectionChanged.Add(treeView);
        }
    }
    
    #endregion

    private static void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        var treeView = (TreeView)sender;
        SetSelectedItemEx(treeView, e.NewValue);
    }

    #region Helper Structures & Methods

    public class MyVirtualizingStackPanel : VirtualizingStackPanel
    {
        /// <summary>
        /// Publically expose BringIndexIntoView.
        /// </summary>
        public void BringIntoView(int index)
        {
            BringIndexIntoView(index);
        }
    }

    /// <summary>Recursively search for an item in this subtree.</summary>
    /// <param name="container">The parent ItemsControl. This can be a TreeView or a TreeViewItem.</param>
    /// <param name="item">The item to search for.</param>
    /// <returns>The TreeViewItem that contains the specified item.</returns>
    private static TreeViewItem GetTreeViewItem(ItemsControl container, object item)
    {
        if (container != null)
        {
            if (container.DataContext == item)
            {
                return container as TreeViewItem;
            }

            // Expand the current container
            if (container is TreeViewItem && !((TreeViewItem)container).IsExpanded)
            {
                container.SetValue(TreeViewItem.IsExpandedProperty, true);
            }

            // Try to generate the ItemsPresenter and the ItemsPanel.
            // by calling ApplyTemplate.  Note that in the 
            // virtualizing case even if the item is marked 
            // expanded we still need to do this step in order to 
            // regenerate the visuals because they may have been virtualized away.

            container.ApplyTemplate();
            ItemsPresenter itemsPresenter =
                (ItemsPresenter)container.Template.FindName("ItemsHost", container);
            if (itemsPresenter != null)
            {
                itemsPresenter.ApplyTemplate();
            }
            else
            {
                // The Tree template has not named the ItemsPresenter, 
                // so walk the descendents and find the child.
                itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                if (itemsPresenter == null)
                {
                    container.UpdateLayout();

                    itemsPresenter = FindVisualChild<ItemsPresenter>(container);
                }
            }

            Panel itemsHostPanel = (Panel)VisualTreeHelper.GetChild(itemsPresenter, 0);


            // Ensure that the generator for this panel has been created.
            UIElementCollection children = itemsHostPanel.Children;

            MyVirtualizingStackPanel virtualizingPanel =
                itemsHostPanel as MyVirtualizingStackPanel;

            for (int i = 0, count = container.Items.Count; i < count; i++)
            {
                TreeViewItem subContainer;
                if (virtualizingPanel != null)
                {
                    // Bring the item into view so 
                    // that the container will be generated.
                    virtualizingPanel.BringIntoView(i);

                    subContainer =
                        (TreeViewItem)container.ItemContainerGenerator.
                        ContainerFromIndex(i);
                }
                else
                {
                    subContainer =
                        (TreeViewItem)container.ItemContainerGenerator.
                        ContainerFromIndex(i);

                    // Bring the item into view to maintain the 
                    // same behavior as with a virtualizing panel.
                    subContainer.BringIntoView();
                }

                if (subContainer != null)
                {
                    // Search the next level for the object.
                    TreeViewItem resultContainer = GetTreeViewItem(subContainer, item);
                    if (resultContainer != null)
                    {
                        return resultContainer;
                    }
                    else
                    {
                        // The object is not under this TreeViewItem
                        // so collapse it.
                        subContainer.IsExpanded = false;
                    }
                }
            }
        }

        return null;
    }

    /// <summary>Search for an element of a certain type in the visual tree.</summary>
    /// <typeparam name="T">The type of element to find.</typeparam>
    /// <param name="visual">The parent element.</param>
    /// <returns></returns>
    private static T FindVisualChild<T>(Visual visual) where T : Visual
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
        {
            Visual child = (Visual)VisualTreeHelper.GetChild(visual, i);
            if (child != null)
            {
                T correctlyTyped = child as T;
                if (correctlyTyped != null)
                {
                    return correctlyTyped;
                }

                T descendent = FindVisualChild<T>(child);
                if (descendent != null)
                {
                    return descendent;
                }
            }
        }
        return null;
    }
    
    #endregion
}

And this is an example of how the TreeView line looks like in XAML:这是 TreeView 行在 XAML 中的外观示例:

<TreeView x:Name="trvwSs"
    Grid.Column="2" Grid.Row="1" Margin="4" ItemsSource="{Binding ItemsTreeViewSs}"
    behaviors:TreeViewSelectedItemExBehavior.SelectedItemEx="{Binding SelectedItemTreeViewSs}" />

Only thing to worry about is to make sure your view-model property that you about to bound to SelectedItemEx is not null.唯一需要担心的是确保您将要绑定到 SelectedItemEx 的视图模型属性不为空。 But that is not a special case.. Just mentioned it in case people get confused.但这不是一个特例.. 只是提到它以防人们感到困惑。

public class VmMainContainer : INotifyPropertyChanged
{
    private object selectedItemTreeViewSs = new object();
    private ObservableCollection<object> selectedItemsTreeViewSs = new ObservableCollection<object>();
    private ObservableCollection<VmItem> itemsTreeViewSs = new ObservableCollection<VmItem>();

    public object SelectedItemTreeViewSs
    {
        get
        {
            return selectedItemTreeViewSs;
        }
        set
        {
            selectedItemTreeViewSs = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemTreeViewSs)));
        }
    }

    public ObservableCollection<object> SelectedItemsTreeViewSs
    {
        get
        {
            return selectedItemsTreeViewSs;
        }
        set
        {
            selectedItemsTreeViewSs = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemsTreeViewSs)));
        }
    }

    public ObservableCollection<VmItem> ItemsTreeViewSs
    {
        get { return itemsTreeViewSs; }
        set
        {
            itemsTreeViewSs = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ItemsTreeViewSs)));
        }
    }
}

And last thing.. example of selecting programmatically: I created a button on my MainWindow.xaml and from its handler..最后一件事.. 以编程方式选择的示例:我在 MainWindow.xaml 及其处理程序中创建了一个按钮..

private void Button_Click(object sender, RoutedEventArgs e)
{
    TreeViewSelectedItemExBehavior.SetSelectedItemEx(trvwSs, trvwSs.Items[3]);
    //TreeViewSelectedItemExBehavior.SetSelectedItemEx(trvwSs, null);
}

Hope this helps someone :)希望这对某人有所帮助:)

You can do it via code behind like你可以通过后面的代码来做到这一点

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

The proposed answer doesn't work.建议的答案不起作用。 @fandisusanto's answer probably does work, but it can be made simpler. @fandisusanto 的答案可能确实有效,但可以更简单。 This is the simplest answer I can come up with:这是我能想到的最简单的答案:

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

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

Usage:用法:

    private void ClearSelectedItem()
    {
        if (AssetTreeView.SelectedItem != null)
        {
            DeselectTreeViewItem(AssetTreeView.Items.Cast<TreeViewItem>());
        }
    }

This is my solution.这是我的解决方案。 The others failed for me in various ways.其他人以各种方式为我失败。 You need to walk the tree from top to bottom, looking for the tree item at each level, expanding and updating the layout along the way.您需要从上到下遍历树,在每个级别查找树项,并在此过程中扩展和更新布局。

This function takes a stack of nodes where the first one out of the stack is the top most node, and each subsequent node on the stack is a child of the previous parent.此函数采用节点堆栈,其中堆栈中的第一个节点是最顶部的节点,堆栈上的每个后续节点都是前一个父节点的子节点。 The second argument is the TreeView.第二个参数是 TreeView。

As each item is found, that item is expanded, and the final item is returned, where the caller can select it.找到每个项目后,该项目将展开,并返回最后一个项目,调用者可以在其中选择它。

    TreeViewItem FindTreeViewItem( Stack<object> nodeStack, TreeView treeView )
    {
        ItemsControl itemsControl = treeView;

        while (nodeStack.Count > 0) {
            object node = nodeStack.Pop();
            bool found = false;

            foreach (object item in itemsControl.Items) {
                if (item == node) {
                    found = true;

                    if (itemsControl.ItemContainerGenerator.ContainerFromItem( item ) is TreeViewItem treeViewItem) {
                        if (nodeStack.Count == 0) {
                            return treeViewItem;
                        }

                        itemsControl = treeViewItem;
                        treeViewItem.IsExpanded = true;
                        treeViewItem.UpdateLayout();
                        break;
                    }
                }
            }

            if (!found) {
                return null;
            }
        }

        return null;
    }

Example of how to call it:如何调用它的示例:

    // Build nodeStack here from your data

    TreeViewItem treeViewItem = FindTreeViewItem( nodeStack, treeView );

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

Try with this试试这个

    /// <summary>
    /// Selects the tree view item.
    /// </summary>
    /// <param name="Collection">The collection.</param>
    /// <param name="Value">The value.</param>
    /// <returns></returns>
    private TreeViewItem SelectTreeViewItem(ItemCollection Collection, String Value)
    {
        if (Collection == null) return null;
        foreach(TreeViewItem Item in Collection)
        {
            /// Find in current
            if (Item.Header.Equals(Value))
            {
                Item.IsSelected = true;
                return Item;
            }
            /// Find in Childs
            if (Item.Items != null)
            {
                TreeViewItem childItem = this.SelectTreeViewItem(Item.Items, Value);
                if (childItem != null)
                {
                    Item.IsExpanded = true;
                    return childItem;
                }
            }
        }
        return null;
    }

Reference: http://amastaneh.blogspot.com/2011/06/wpf-selectedvalue-for-treeview.html参考: http : //amastaneh.blogspot.com/2011/06/wpf-selectedvalue-for-treeview.html

I wrote a Helper class for this, which supports MVVM and lazy loaded items.我为此编写了一个 Helper 类,它支持 MVVM 和延迟加载项。

public class TreeViewHelper<TModel>
{
    public TreeViewHelper(TreeView treeView, Func<TModel, TModel> getParent, Func<TModel, IList<TModel>> getSubItems)
    {
        TreeView = treeView;
        GetParent = getParent;
        GetSubItems = getSubItems;
    }

    public TreeView TreeView { get; }
    public Func<TModel, TModel> GetParent { get; }
    public Func<TModel, IList<TModel>> GetSubItems { get; }

    public void SelectItemWhileLoaded(TModel node, IList<TModel> rootNodes)
    {
        if (TreeView.IsLoaded)
        {
            SelectItem(node, rootNodes);
        }
        else
        {
            TreeView.Loaded += TreeView_Loaded;
            void TreeView_Loaded(object sender, System.Windows.RoutedEventArgs e)
            {
                TreeView.Loaded -= TreeView_Loaded;
                SelectItem(node, rootNodes);
            }
        }
    }


    public void SelectItem(TModel node, IList<TModel> rootNodes)
    {
        Stack<TModel> nodes = new Stack<TModel>();
        //push into stack
        while (!rootNodes.Contains(node))
        {
            nodes.Push(node);
            node = GetParent(node);
        }
        TreeViewItem treeViewItem = TreeView.ItemContainerGenerator
            .ContainerFromItem(node) as TreeViewItem;
        if (nodes.Count == 0)
        {
            //Top level
            treeViewItem.IsSelected = true;
            treeViewItem.BringIntoView();
            return;
        }
        Expanded(true);
        void Expanded(bool top)
        {
            if (!top)
            {
                treeViewItem = treeViewItem.ItemContainerGenerator
                    .ContainerFromItem(node) as TreeViewItem;
                if (nodes.Count == 0)
                {
                    treeViewItem.IsSelected = true;
                    treeViewItem.BringIntoView();
                    return;
                }
            }
            node = nodes.Pop();
            treeViewItem.IsExpanded = true;
            if (treeViewItem.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                Expanded(true);
            }
            else
            {
                //Lazy
                treeViewItem.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
            }
        }
        void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
        {
            if (treeViewItem.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
            {
                treeViewItem.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
                Expanded(false);
            }
        }
    }
}

I think this is the simplest solution:我认为这是最简单的解决方案:

private void MouseDownEventProcessing(TreeNodeMouseClickEventArgs e)
{
    tvEmployeeDirectory.SelectedNode = e.Node;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM