mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 10:35:27 +08:00 
			
		
		
		
	Fix tree rendering
Fixes some tree rendering problems where lines were not properly drawn at some levels during some circumstances. * Change the API back to only allow one root. * Now uses a stack based approach to rendering instead of recursion. * Removes the need for measuring the whole tree in advance. Leave this up to each child to render.
This commit is contained in:
		
				
					committed by
					
						
						Patrik Svensson
					
				
			
			
				
	
			
			
			
						parent
						
							0e0f4b4220
						
					
				
				
					commit
					8261b25e5c
				
			@@ -1,23 +1,24 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Spectre.Console.Rendering;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="IHasCulture"/>.
 | 
			
		||||
    /// Contains extension methods for <see cref="IHasTreeNodes"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class HasTreeNodeExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a tree node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree node to.</param>
 | 
			
		||||
        /// <param name="markup">The node's markup text.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNode<T>(this T obj, string markup)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        /// <returns>The added tree node.</returns>
 | 
			
		||||
        public static TreeNode AddNode<T>(this T obj, string markup)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
@@ -35,31 +36,12 @@ namespace Spectre.Console
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a tree node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <param name="markup">The node's markup text.</param>
 | 
			
		||||
        /// <param name="action">An action that can be used to configure the created node further.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNode<T>(this T obj, string markup, Action<TreeNode> action)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (markup is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(markup));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return AddNode(obj, new Markup(markup), action);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a tree node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree node to.</param>
 | 
			
		||||
        /// <param name="renderable">The renderable to add.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNode<T>(this T obj, IRenderable renderable)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        /// <returns>The added tree node.</returns>
 | 
			
		||||
        public static TreeNode AddNode<T>(this T obj, IRenderable renderable)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
@@ -71,52 +53,20 @@ namespace Spectre.Console
 | 
			
		||||
                throw new ArgumentNullException(nameof(renderable));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Children.Add(new TreeNode(renderable));
 | 
			
		||||
            return obj;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a tree node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <param name="renderable">The renderable to add.</param>
 | 
			
		||||
        /// <param name="action">An action that can be used to configure the created node further.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNode<T>(this T obj, IRenderable renderable, Action<TreeNode> action)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (renderable is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(renderable));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (action is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(action));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var node = new TreeNode(renderable);
 | 
			
		||||
            action(node);
 | 
			
		||||
 | 
			
		||||
            obj.Children.Add(node);
 | 
			
		||||
            return obj;
 | 
			
		||||
            obj.Nodes.Add(node);
 | 
			
		||||
            return node;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a tree node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree node to.</param>
 | 
			
		||||
        /// <param name="node">The tree node to add.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNode<T>(this T obj, TreeNode node)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        /// <returns>The added tree node.</returns>
 | 
			
		||||
        public static TreeNode AddNode<T>(this T obj, TreeNode node)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
@@ -128,19 +78,18 @@ namespace Spectre.Console
 | 
			
		||||
                throw new ArgumentNullException(nameof(node));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Children.Add(node);
 | 
			
		||||
            return obj;
 | 
			
		||||
            obj.Nodes.Add(node);
 | 
			
		||||
            return node;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNodes<T>(this T obj, params string[] nodes)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        public static void AddNodes<T>(this T obj, params string[] nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
@@ -152,19 +101,17 @@ namespace Spectre.Console
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Children.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
 | 
			
		||||
            return obj;
 | 
			
		||||
            obj.Nodes.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object type with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object that has tree nodes.</param>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static T AddNodes<T>(this T obj, params TreeNode[] nodes)
 | 
			
		||||
            where T : class, IHasTreeNodes
 | 
			
		||||
        public static void AddNodes<T>(this T obj, IEnumerable<string> nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
@@ -176,8 +123,95 @@ namespace Spectre.Console
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Children.AddRange(nodes);
 | 
			
		||||
            return obj;
 | 
			
		||||
            obj.Nodes.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        public static void AddNodes<T>(this T obj, params IRenderable[] nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (nodes is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Nodes.AddRange(nodes.Select(node => new TreeNode(node)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        public static void AddNodes<T>(this T obj, IEnumerable<IRenderable> nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (nodes is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Nodes.AddRange(nodes.Select(node => new TreeNode(node)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        public static void AddNodes<T>(this T obj, params TreeNode[] nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (nodes is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Nodes.AddRange(nodes);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add multiple tree nodes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T">An object with tree nodes.</typeparam>
 | 
			
		||||
        /// <param name="obj">The object to add the tree nodes to.</param>
 | 
			
		||||
        /// <param name="nodes">The tree nodes to add.</param>
 | 
			
		||||
        public static void AddNodes<T>(this T obj, IEnumerable<TreeNode> nodes)
 | 
			
		||||
            where T : IHasTreeNodes
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(obj));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (nodes is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(nodes));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.Nodes.AddRange(nodes);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								src/Spectre.Console/Extensions/ListExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/Spectre.Console/Extensions/ListExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    internal static class ListExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static void RemoveLast<T>(this List<T> list)
 | 
			
		||||
        {
 | 
			
		||||
            if (list is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(list));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (list.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                list.RemoveAt(list.Count - 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void AddOrReplaceLast<T>(this List<T> list, T item)
 | 
			
		||||
        {
 | 
			
		||||
            if (list is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(list));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (list.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                list.Add(item);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                list[list.Count - 1] = item;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/Spectre.Console/Extensions/TreeExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/Spectre.Console/Extensions/TreeExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="Tree"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class TreeExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets the tree style.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="tree">The tree.</param>
 | 
			
		||||
        /// <param name="style">The tree style.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static Tree Style(this Tree tree, Style? style)
 | 
			
		||||
        {
 | 
			
		||||
            if (tree is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(tree));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tree.Style = style;
 | 
			
		||||
            return tree;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets the tree guide line appearance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="tree">The tree.</param>
 | 
			
		||||
        /// <param name="guide">The tree guide lines to use.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static Tree Guide(this Tree tree, TreeGuide guide)
 | 
			
		||||
        {
 | 
			
		||||
            if (tree is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(tree));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tree.Guide = guide;
 | 
			
		||||
            return tree;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								src/Spectre.Console/Extensions/TreeGuideExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Spectre.Console/Extensions/TreeGuideExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="TreeGuide"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class TreeGuideExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the safe border for a border.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="guide">The tree guide to get the safe version for.</param>
 | 
			
		||||
        /// <param name="safe">Whether or not to return the safe border.</param>
 | 
			
		||||
        /// <returns>The safe border if one exist, otherwise the original border.</returns>
 | 
			
		||||
        public static TreeGuide GetSafeTreeGuide(this TreeGuide guide, bool safe)
 | 
			
		||||
        {
 | 
			
		||||
            if (guide is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(guide));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (safe && guide.SafeTreeGuide != null)
 | 
			
		||||
            {
 | 
			
		||||
                return guide.SafeTreeGuide;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return guide;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/Spectre.Console/Extensions/TreeNodeExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Spectre.Console/Extensions/TreeNodeExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Spectre.Console
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Contains extension methods for <see cref="TreeNode"/>.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class TreeNodeExtensions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Expands the tree.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="node">The tree node.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static TreeNode Expand(this TreeNode node)
 | 
			
		||||
        {
 | 
			
		||||
            return Expand(node, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Collapses the tree.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="node">The tree node.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static TreeNode Collapse(this TreeNode node)
 | 
			
		||||
        {
 | 
			
		||||
            return Expand(node, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets whether or not the tree node should be expanded.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="node">The tree node.</param>
 | 
			
		||||
        /// <param name="expand">Whether or not the tree node should be expanded.</param>
 | 
			
		||||
        /// <returns>The same instance so that multiple calls can be chained.</returns>
 | 
			
		||||
        public static TreeNode Expand(this TreeNode node, bool expand)
 | 
			
		||||
        {
 | 
			
		||||
            if (node is null)
 | 
			
		||||
            {
 | 
			
		||||
                throw new ArgumentNullException(nameof(node));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            node.Expanded = expand;
 | 
			
		||||
            return node;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user