How to programmatically select an item in a WPF TreeView?

后端 未结 16 2191
时光取名叫无心
时光取名叫无心 2020-11-28 08:42

How is it possible to programmatically select an item in a WPF TreeView? The ItemsControl model seems to prevent it.

相关标签:
16条回答
  • 2020-11-28 09:11

    I think this is the simplest solution:

    private void MouseDownEventProcessing(TreeNodeMouseClickEventArgs e)
    {
        tvEmployeeDirectory.SelectedNode = e.Node;
    }
    
    0 讨论(0)
  • 2020-11-28 09:12

    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;
    }
    
    0 讨论(0)
  • 2020-11-28 09:13

    I wrote a Helper class for this, which supports MVVM and lazy loaded items.

    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);
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 09:14

    The proposed answer doesn't work. @fandisusanto's answer probably does work, but it can be made simpler. 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>());
            }
        }
    
    0 讨论(0)
提交回复
热议问题