diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config index eb184f5625..c3f973faac 100644 --- a/src/Umbraco.Web.UI/config/trees.config +++ b/src/Umbraco.Web.UI/config/trees.config @@ -1,7 +1,7 @@  - + @@ -38,5 +38,5 @@ + iconClosed=".sprTreeFolder" iconOpen=".sprTreeFolder_o" sortOrder="10" />--> \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 9fa1d4238d..d04ef352b0 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -19,12 +19,15 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees { + [LegacyBaseTree(typeof(loadContent))] [Tree(Constants.Applications.Content, Constants.Trees.Content, "Content")] [PluginController("UmbracoTrees")] public class ContentTreeController : ContentTreeControllerBase { protected override TreeNode CreateRootNode(FormDataCollection queryStrings) { + TreeNode node; + //if the user's start node is not default, then return their start node as the root node. if (UmbracoUser.StartNodeId != Constants.System.Root) { @@ -35,20 +38,27 @@ namespace Umbraco.Web.Trees throw new HttpResponseException(HttpStatusCode.NotFound); } - var node = new TreeNode( + node = new TreeNode( userRoot.Id.ToInvariantString(), "", //root nodes aren't expandable, no need to lookup the child nodes url Url.GetMenuUrl(GetType(), userRoot.Id.ToInvariantString(), queryStrings)) - { - HasChildren = true, - RoutePath = currApp, - Title = userRoot.Name - }; + { + HasChildren = true, + RoutePath = currApp, + Title = userRoot.Name + }; - return node; + + } + else + { + node = base.CreateRootNode(queryStrings); } - return base.CreateRootNode(queryStrings); + //InjectLegacyTreeCompatibility(node, queryStrings); + + return node; + } protected override int RecycleBinId @@ -74,13 +84,16 @@ namespace Umbraco.Web.Trees var allowedUserOptions = GetUserMenuItemsForNode(e); if (CanUserAccessNode(e, allowedUserOptions)) { - nodes.Add( - CreateTreeNode( + var node = CreateTreeNode( e.Id.ToInvariantString(), queryStrings, e.Name, e.ContentTypeIcon, - e.HasChildren)); + e.HasChildren); + + //InjectLegacyTreeCompatibility(node, queryStrings); + + nodes.Add(node); } } return nodes; @@ -164,6 +177,23 @@ namespace Umbraco.Web.Trees return menu; } + ///// + ///// This is required so that the legacy tree dialog pickers and the legacy TreeControl.ascx stuff works with these new trees. + ///// + ///// + ///// + ///// + ///// NOTE: That if developers create brand new trees using webapi controllers then they'll need to manually make it + ///// compatible with the legacy tree pickers, 99.9% of the time devs won't be doing that and once we make the new tree + ///// pickers and devs update their apps to be angularized it won't matter + ///// + //private void InjectLegacyTreeCompatibility(TreeNode node, FormDataCollection queryStrings) + //{ + // if (IsDialog(queryStrings)) + // { + // node.AdditionalData["legacyDialogAction"] = "javascript:openContent(" + node.NodeId + ");"; + // } + //} } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index 4d26e3dd36..fe8901db35 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -58,15 +58,20 @@ namespace Umbraco.Web.Trees { if (id == Constants.System.Root.ToInvariantString()) { - //we need to append the recycle bin to the end + //we need to append the recycle bin to the end (if not in dialog mode) var nodes = PerformGetTreeNodes(id, queryStrings); - nodes.Add(CreateTreeNode( - Constants.System.RecycleBinContent.ToInvariantString(), - queryStrings, - ui.GetText("general", "recycleBin"), - "icon-trash", - RecycleBinSmells, - queryStrings.GetValue("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin")); + + if (!IsDialog(queryStrings)) + { + nodes.Add(CreateTreeNode( + Constants.System.RecycleBinContent.ToInvariantString(), + queryStrings, + ui.GetText("general", "recycleBin"), + "icon-trash", + RecycleBinSmells, + queryStrings.GetValue("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin")); + } + return nodes; } diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 5ebd57026d..ca3f67cddc 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http.Formatting; +using System.Text; using System.Web; using System.Web.Http.Routing; using Umbraco.Core; @@ -15,12 +17,97 @@ using umbraco.interfaces; namespace Umbraco.Web.Trees { + [AttributeUsage(AttributeTargets.Class)] + internal sealed class LegacyBaseTreeAttribute : Attribute + { + public Type BaseTreeType { get; private set; } + + public LegacyBaseTreeAttribute(Type baseTreeType) + { + if (!TypeHelper.IsTypeAssignableFrom(baseTreeType)) + { + throw new InvalidOperationException("The type for baseTreeType must be assignable from " + typeof(BaseTree)); + } + + BaseTreeType = baseTreeType; + } + } + + internal class LegacyBaseTreeWrapper : BaseTree + { + + private readonly string _treeAlias; + private readonly TreeNodeCollection _children; + private readonly TreeNode _root; + + public LegacyBaseTreeWrapper(string treeAlias, string application, TreeNode root, TreeNodeCollection children = null) + : base(application) + { + _treeAlias = treeAlias; + _root = root; + _children = children; + } + + public override void RenderJS(ref StringBuilder javascript) + { + + } + + public override void Render(ref XmlTree tree) + { + foreach (var c in _children) + { + var node = XmlTreeNode.Create(this); + LegacyTreeDataConverter.ConvertToLegacyNode(node, c, _treeAlias); + node.Source = IsDialog == false ? GetTreeServiceUrl(int.Parse(node.NodeID)) : GetTreeDialogUrl(int.Parse(node.NodeID)); + tree.Add(node); + } + } + + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + rootNode.NodeID = _root.NodeId; + rootNode.Icon = _root.IconIsClass ? _root.Icon.EnsureStartsWith('.') : _root.IconFilePath; + rootNode.HasChildren = _root.HasChildren; + rootNode.NodeID = _root.NodeId; + rootNode.Text = _root.Title; + rootNode.NodeType = _root.NodeType; + rootNode.OpenIcon = _root.IconIsClass ? _root.Icon.EnsureStartsWith('.') : _root.IconFilePath; + } + + public override string TreeAlias + { + get { return _treeAlias; } + } + } + /// /// Converts the legacy tree data to the new format /// internal class LegacyTreeDataConverter { - + + internal static FormDataCollection ConvertFromLegacyTreeParams(TreeRequestParams treeParams) + { + return new FormDataCollection(new Dictionary + { + {TreeQueryStringParameters.Application, treeParams.Application}, + {TreeQueryStringParameters.DialogMode, treeParams.IsDialog.ToString()}, + }); + } + + internal static void ConvertToLegacyNode(XmlTreeNode legacy, TreeNode node, string treeType) + { + legacy.Action = node.AdditionalData.ContainsKey("legacyDialogAction") ? node.AdditionalData["legacyDialogAction"].ToString() : ""; + legacy.HasChildren = node.HasChildren; + legacy.Icon = node.IconIsClass ? node.Icon.EnsureStartsWith('.') : node.IconFilePath; + legacy.NodeID = node.NodeId; + legacy.NodeType = node.NodeType; + legacy.OpenIcon = node.IconIsClass ? node.Icon.EnsureStartsWith('.') : node.IconFilePath; + legacy.Text = node.Title; + legacy.TreeType = treeType; + } + /// /// Gets the menu item collection from a legacy tree node based on it's parent node's child collection /// diff --git a/src/Umbraco.Web/Trees/TreeApiController.cs b/src/Umbraco.Web/Trees/TreeApiController.cs index e7adaadd48..bd88348b4d 100644 --- a/src/Umbraco.Web/Trees/TreeApiController.cs +++ b/src/Umbraco.Web/Trees/TreeApiController.cs @@ -102,9 +102,8 @@ namespace Umbraco.Web.Trees node.AdditionalData.Add("searchable", "true"); } - //now update all data based on some of the query strings, like if we are running in dialog mode - var isDialog = queryStrings.GetValue(TreeQueryStringParameters.DialogMode); - if (isDialog) + //now update all data based on some of the query strings, like if we are running in dialog mode + if (IsDialog(queryStrings)) { node.RoutePath = "#"; } @@ -137,9 +136,8 @@ namespace Umbraco.Web.Trees AddQueryStringsToAdditionalData(node, queryStrings); } - //now update all data based on some of the query strings, like if we are running in dialog mode - var isDialog = queryStrings.GetValue(TreeQueryStringParameters.DialogMode); - if (isDialog) + //now update all data based on some of the query strings, like if we are running in dialog mode + if (IsDialog((queryStrings))) { foreach (var node in nodes) { @@ -288,17 +286,19 @@ namespace Umbraco.Web.Trees #endregion - ///// - ///// The tree name based on the controller type so that everything is based on naming conventions - ///// - //public string TreeType - //{ - // get - // { - // var name = GetType().Name; - // return name.Substring(0, name.LastIndexOf("TreeController", StringComparison.Ordinal)); - // } - //} + #region Query String parameter helpers + + /// + /// If the request is for a dialog mode tree + /// + /// + /// + protected bool IsDialog(FormDataCollection queryStrings) + { + return queryStrings.GetValue(TreeQueryStringParameters.DialogMode); + } + + #endregion public static event EventHandler TreeNodesRendering; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs index 4202ba0d74..a06adb1f2d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs @@ -84,6 +84,7 @@ namespace umbraco.cms.presentation.Trees return m_treeAlias; } + internal set { m_treeAlias = value; } } private string m_treeAlias; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs index 78b31f34d4..67d325f118 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs @@ -14,6 +14,7 @@ namespace umbraco /// Handles loading the content tree into umbraco's application tree /// [Obsolete("This is no longer used and will be removed from the codebase in the future")] + //[Tree(Constants.Applications.Content, "content", "Content", silent: true)] public class loadContent : BaseContentTree { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeClientService.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeClientService.asmx.cs index 64a424ebb4..886eb71c89 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeClientService.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeClientService.asmx.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Net.Http.Formatting; using System.Web; @@ -10,8 +11,12 @@ using System.Web.Http.Routing; using System.Web.Mvc; using System.Web.Routing; using System.Web.Services; +using Umbraco.Core; +using Umbraco.Web; using Umbraco.Web.WebApi; using Umbraco.Web.WebServices; +using umbraco.BusinessLogic; +using umbraco.businesslogic; using umbraco.presentation.umbraco.controls; using umbraco.cms.presentation.Trees; using System.Web.Script.Services; @@ -64,6 +69,9 @@ namespace umbraco.presentation.webservices } else { + BaseTree tree = null; + var xTree = new XmlTree(); + //first get the app tree definition so we can then figure out if we need to load by legacy or new //now we'll look up that tree var appTree = Services.ApplicationTreeService.GetByAlias(treeType); @@ -73,34 +81,79 @@ namespace umbraco.presentation.webservices var controllerAttempt = appTree.TryGetControllerTree(); if (controllerAttempt.Success) { - var context = WebApiHelper.CreateContext(new HttpMethod("GET"), Context.Request.Url, new HttpContextWrapper(Context)); - - var rootAttempt = appTree.TryGetRootNodeFromControllerTree( - new FormDataCollection(new Dictionary {{"app", app}}), - context); - - if (rootAttempt.Success) + var legacyAtt = controllerAttempt.Result.GetCustomAttribute(false); + if (legacyAtt == null) { - + throw new InvalidOperationException("Cannot render a " + typeof (TreeApiController) + " tree type with the legacy web services unless attributed with " + typeof (LegacyBaseTreeAttribute)); } + + var treeDef = new TreeDefinition( + legacyAtt.BaseTreeType, + new ApplicationTree(false, true, appTree.SortOrder, appTree.ApplicationAlias, appTree.Alias, appTree.Title, appTree.IconClosed, appTree.IconOpened, "", legacyAtt.BaseTreeType.GetFullNameWithAssembly(), ""), + new Application(treeType, treeType, "", 0)); + + tree = treeDef.CreateInstance(); + tree.TreeAlias = appTree.Alias; + + //var queryStrings = new FormDataCollection(new Dictionary + // { + // {TreeQueryStringParameters.Application, app}, + // {TreeQueryStringParameters.DialogMode, isDialog.ToString()} + // }); + + //var context = WebApiHelper.CreateContext(new HttpMethod("GET"), Context.Request.Url, new HttpContextWrapper(Context)); + + //var rootAttempt = appTree.TryGetRootNodeFromControllerTree( + // queryStrings, + // context); + + //if (rootAttempt.Success) + //{ + // tree = new LegacyBaseTreeWrapper(treeType, app, rootAttempt.Result); + //} + } + else + { + //get the tree that we need to render + + var treeDef = TreeDefinitionCollection.Instance.FindTree(treeType); + //if (treeDef == null) + //{ + // // Load all LEGACY Trees by attribute and add them to the XML config + // var legacyTreeTypes = PluginManager.Current.ResolveAttributedTrees(); + // var found = legacyTreeTypes + // .Select(x => new { att = x.GetCustomAttribute(false), type = x }) + // .FirstOrDefault(x => x.att.Alias == treeType); + // if (found == null) + // { + // throw new InvalidOperationException("The " + GetType() + " service can only return data for legacy tree types"); + // } + // treeDef = new TreeDefinition( + // found.type, + // new ApplicationTree(found.att.Silent, found.att.Initialize, (byte)found.att.SortOrder, found.att.ApplicationAlias, found.att.Alias, found.att.Title, found.att.IconClosed, found.att.IconOpen, "", found.type.GetFullNameWithAssembly(), found.att.Action), + // new Application(treeType, treeType, "", 0)); + + // tree = treeDef.CreateInstance(); + //} + //else + //{ + // tree = treeDef.CreateInstance(); + //} + + tree = treeDef.CreateInstance(); } - var legacyAttempt = appTree.TryGetLegacyTreeDef(); - - - //get the tree that we need to render - var tree = TreeDefinitionCollection.Instance.FindTree(treeType).CreateInstance(); tree.ShowContextMenu = showContextMenu; tree.IsDialog = isDialog; tree.DialogMode = dialogMode; tree.NodeKey = string.IsNullOrEmpty(nodeKey) ? "" : nodeKey; tree.FunctionToCall = string.IsNullOrEmpty(functionToCall) ? "" : functionToCall; //this would be nice to set, but no parameters :( - //tree.StartNodeID = + //tree.StartNodeID = //now render it's start node - var xTree = new XmlTree(); xTree.Add(tree.RootNode); + returnVal.Add("json", xTree.ToString()); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeDataService.ashx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeDataService.ashx.cs index ebd49d7af4..dbc7113c0d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeDataService.ashx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/TreeDataService.ashx.cs @@ -1,115 +1,172 @@ using System; using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Runtime.Remoting.Contexts; using System.Web; using System.Web.Services; +using Umbraco.Core; +using Umbraco.Web.Trees; +using Umbraco.Web.WebApi; using Umbraco.Web.WebServices; +using umbraco.BusinessLogic; +using umbraco.cms.presentation; using umbraco.cms.presentation.Trees; using System.Threading; namespace umbraco.presentation.webservices { - /// - /// Summary description for TreeDataService - /// - [WebService(Namespace = "http://tempuri.org/")] - [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] - [System.ComponentModel.ToolboxItem(false)] - public class TreeDataService : UmbracoAuthorizedHttpHandler - { + /// + /// Summary description for TreeDataService + /// + [WebService(Namespace = "http://tempuri.org/")] + [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] + [System.ComponentModel.ToolboxItem(false)] + public class TreeDataService : UmbracoAuthorizedHttpHandler + { - public override void ProcessRequest(HttpContext context) - { - AuthorizeRequest(true); - context.Response.ContentType = "application/json"; - context.Response.Write(GetXmlTree().ToString()); + public override void ProcessRequest(HttpContext context) + { + AuthorizeRequest(true); + context.Response.ContentType = "application/json"; + context.Response.Write(GetXmlTree(context).ToString()); - } + } - public override bool IsReusable - { - get - { - return false; - } - } + public override bool IsReusable + { + get + { + return false; + } + } [Obsolete("Use the base class AuthorizeRequest methods in UmbracoAuthorizedHttpHandler")] - public static void Authorize() - { - if (!BasePages.BasePage.ValidateUserContextID(BasePages.BasePage.umbracoUserContextID)) - throw new Exception("Client authorization failed. User is not logged in"); + public static void Authorize() + { + if (!BasePages.BasePage.ValidateUserContextID(BasePages.BasePage.umbracoUserContextID)) + throw new Exception("Client authorization failed. User is not logged in"); - } + } - /// - /// Returns the an XmlTree based on the current http request - /// - /// - public XmlTree GetXmlTree() - { - var treeParams = TreeRequestParams.FromQueryStrings(); + /// + /// Returns the an XmlTree based on the current http request + /// + /// + public XmlTree GetXmlTree(HttpContext context) + { + var treeParams = TreeRequestParams.FromQueryStrings(); //validate the current user for the request app! AuthorizeRequest(treeParams.Application, true); - if (string.IsNullOrEmpty(treeParams.TreeType)) - if (!string.IsNullOrEmpty(treeParams.Application)) - LoadAppTrees(treeParams); - else - return new XmlTree(); //returns an empty tree - else - LoadTree(treeParams); + if (string.IsNullOrEmpty(treeParams.TreeType)) + if (!string.IsNullOrEmpty(treeParams.Application)) + LoadAppTrees(treeParams, context); + else + return new XmlTree(); //returns an empty tree + else + LoadTree(treeParams, context); - return _xTree; - } + return _xTree; + } - private XmlTree _xTree = new XmlTree(); + private XmlTree _xTree = new XmlTree(); - /// - /// If the application supports multiple trees, then this function iterates over all of the trees assigned to it - /// and creates their top level nodes and context menus. - /// + /// + /// If the application supports multiple trees, then this function iterates over all of the trees assigned to it + /// and creates their top level nodes and context menus. + /// /// - private void LoadAppTrees(TreeRequestParams treeParams) - { - //find all tree definitions that have the current application alias - List treeDefs = TreeDefinitionCollection.Instance.FindActiveTrees(treeParams.Application); + /// + private void LoadAppTrees(TreeRequestParams treeParams, HttpContext context) + { + //find all tree definitions that have the current application alias + List treeDefs = TreeDefinitionCollection.Instance.FindActiveTrees(treeParams.Application); - foreach (TreeDefinition treeDef in treeDefs) - { - BaseTree bTree = treeDef.CreateInstance(); - bTree.SetTreeParameters(treeParams); - _xTree.Add(bTree.RootNode); - } - } + foreach (TreeDefinition treeDef in treeDefs) + { + BaseTree bTree = treeDef.CreateInstance(); + bTree.SetTreeParameters(treeParams); + _xTree.Add(bTree.RootNode); + } + } - /// - /// This will load the particular ITree object and call it's render method to get the nodes that need to be rendered. - /// + /// + /// This will load the particular ITree object and call it's render method to get the nodes that need to be rendered. + /// /// - private void LoadTree(TreeRequestParams treeParams) - { + /// + private void LoadTree(TreeRequestParams treeParams, HttpContext httpContext) + { - TreeDefinition treeDef = TreeDefinitionCollection.Instance.FindTree(treeParams.TreeType); + var appTree = Services.ApplicationTreeService.GetByAlias(treeParams.TreeType); + if (appTree == null) + throw new InvalidOperationException("No tree found with alias " + treeParams.TreeType); - if (treeDef != null) - { - BaseTree bTree = treeDef.CreateInstance(); - bTree.SetTreeParameters(treeParams); - bTree.Render(ref _xTree); - } - else - LoadNullTree(treeParams); - } + var controllerAttempt = appTree.TryGetControllerTree(); + if (controllerAttempt.Success) + { + var legacyAtt = controllerAttempt.Result.GetCustomAttribute(false); + if (legacyAtt == null) + { + throw new InvalidOperationException("Cannot render a " + typeof(TreeApiController) + " tree type with the legacy web services unless attributed with " + typeof(LegacyBaseTreeAttribute)); + } - /// - /// Load an empty tree structure to show the end user that there was a problem loading the tree. - /// - private void LoadNullTree(TreeRequestParams treeParams) - { - BaseTree nullTree = new NullTree(treeParams.Application); - nullTree.SetTreeParameters(treeParams); - nullTree.Render(ref _xTree); - } - } + var treeDef = new TreeDefinition( + legacyAtt.BaseTreeType, + new ApplicationTree(false, true, appTree.SortOrder, appTree.ApplicationAlias, appTree.Alias, appTree.Title, appTree.IconClosed, appTree.IconOpened, "", legacyAtt.BaseTreeType.GetFullNameWithAssembly(), ""), + new Application(treeParams.TreeType, treeParams.TreeType, "", 0)); + + var tree = treeDef.CreateInstance(); + tree.TreeAlias = appTree.Alias; + tree.SetTreeParameters(treeParams); + tree.Render(ref _xTree); + + //var context = WebApiHelper.CreateContext(new HttpMethod("GET"), httpContext.Request.Url, new HttpContextWrapper(httpContext)); + + //var rootAttempt = appTree.TryGetRootNodeFromControllerTree( + // LegacyTreeDataConverter.ConvertFromLegacyTreeParams(treeParams), + // context); + + //var nodesAttempt = appTree.TryLoadFromControllerTree( + // treeParams.StartNodeID.ToInvariantString(), + // LegacyTreeDataConverter.ConvertFromLegacyTreeParams(treeParams), + // context); + + //if (rootAttempt.Success && nodesAttempt.Success) + //{ + // var tree = new LegacyBaseTreeWrapper(treeParams.TreeType, treeParams.Application, rootAttempt.Result, nodesAttempt.Result); + // tree.SetTreeParameters(treeParams); + // tree.Render(ref _xTree); + //} + } + else + { + var treeDef = TreeDefinitionCollection.Instance.FindTree(treeParams.TreeType); + + if (treeDef != null) + { + var bTree = treeDef.CreateInstance(); + bTree.SetTreeParameters(treeParams); + bTree.Render(ref _xTree); + } + else + LoadNullTree(treeParams); + } + + + + } + + /// + /// Load an empty tree structure to show the end user that there was a problem loading the tree. + /// + private void LoadNullTree(TreeRequestParams treeParams) + { + BaseTree nullTree = new NullTree(treeParams.Application); + nullTree.SetTreeParameters(treeParams); + nullTree.Render(ref _xTree); + } + } }