Need help - new to RadTreeList control

3 posts, 0 answers
  1. Alex
    Alex avatar
    19 posts
    Member since:
    Nov 2011

    Posted 02 May 2012 Link to this post

    Hey gang -

    I'm building a new page that needs to allow the user to select a person in the corporate hierarchy, then see that person's direct reports, with some columnar data. So I'm using the RadTreeList control because it appears to be the right tool for the job.

    However, I'm struggling with getting beyond the simplest initial implementation (one guy and his immediate direct reports). I've looked around on the forum for answers, but can't find anything that will get me over the hump (probably asking my questions incorrectly). Hopefully, I can glean what I need by asking for help all at once. Thanks in advance for help on...

    Here are the problems I'm running in to, mostly around getting a specific value (samAccountName) for a selected item and databinding on demand.

    1. The corporate hierarchy is quite large, so I'm only wanting to load the direct reports when a person clicks on a person within the hierarchy. Otherwise, the CEO and several upper managers will get timeouts when they load the page (because of the large hierarchy). I know the system can handle on-demand loading of child elements, though I cannot figure out how to do it.

      I'm building the initial collection of objects via a WCF service when the user first enters the page, based on their AD Sam Account Name. The collection includes an (int) ID and (int) ParentID - as I understand this is the only way to properly indicate the hierarchical relationships. This is a short list as a rule, and it works for the first load of the page (I'm using the NeedDataSource event handler for all this so far).

      I see the individual and their immediate direct reports (but these reports don't have an expander (+/-) button because I haven't loaded their direct reports - I want to do that on selection).

      I have a method that can check if a person has direct reports, so I can call that for each person in the direct reports list, but how do I show the expander button if they have reports without loading any data yet? I don't want to load that person's direct reports until they have been selected.

    2. Which leads me to the second problem: How do I append a selected person's direct reports to the current treelist's collection on selection? I know I can get the list of items, convert to a collection, append the new direct reports items, and rebind... but... 

    3. How do I get the selected person's Sam Account Name (which is bound to the item, so I know it's available)? 

    4. Which event should fire to reconstitute the collection and rebind?

    5. If I can get the info to do all of that on the correct event handler, then the only other thing I need to know is how can I make a column value (i.e. the person's full name) be the actual selectable button instead of the expander icon? This would be preferable.

    6. Is the RadTreeView the right control for this job???

    I know I'm asking numerous questions all at once. I'm hoping the answers are very straightforward. I have to get this thing ready for a demo within the next week.

    Again - thanks very much for all the help you can provide in solving this set of dilemmas.
    A
  2. Alex
    Alex avatar
    19 posts
    Member since:
    Nov 2011

    Posted 02 May 2012 Link to this post

    So I simplified my implementation in order to figure out how this thing works - but I cannot get the Load On Demand to function properly. I followed the tutorials and it always dies with "Object not set to an instance..." whenever I try to expand the very first node.

    If I debug through, the collection appears to be built correctly. I think the markup may be the problem... I just don't know. Here's what I have so far.
    HTML:
    <telerik:RadTreeList ID="RadTreeList2" DataKeyNames="Id" ParentDataKeyNames="ParentId"
            runat="server" AutoGenerateColumns="true" Width="100%" AllowLoadOnDemand="true"
            onneeddatasource="RadTreeList2_NeedDataSource" 
            onchilditemsdatabind="RadTreeList2_ChildItemsDataBind">
    </telerik:RadTreeList>

    CODE:

    On Load handler...
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e); 
        this.RadTreeList2.DataBind();
    }

    NeedDataSource handler...
    protected void RadTreeList2_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
            {
                    List<SimpleItem> itemList = new List<SimpleItem>();
     
                    if (this.Session["MyItems"] != null)
                    {
                        itemList = (List<SimpleItem>)this.Session["MyItems"];
                    }
     
                    this.AddAnItem(null, itemList);
     
                    this.Session["MyItems"] = itemList;
     
                    this.RadTreeList2.DataSource = itemList;
            }

    The code to add an item to the list (in reality, I'd be adding new items via a DB query that returns a collection of objects)...
    private IList<SimpleItem> AddAnItem(string currentId, IList<SimpleItem> itemList)
            {
                bool isFound = false;
     
                if (!String.IsNullOrEmpty(currentId))
                {
                    //make sure the id doesn't exist in collection yet.
                    foreach (var item in itemList)
                    {
                        if (currentId == item.Id)
                        {
                            isFound = true;
                            break;
                        }
                    }
                }
     
                if (!isFound)
                {
                    //add item.
                    itemList.Add(new SimpleItem()
                    {
                        Id = (itemList.Count() + 1).ToString(),
                        ParentId = (itemList.Count() == 0) ? null : itemList.Count().ToString(),
                        Name = (itemList.Count() + 1).ToString()
                    });
                }
     
                return itemList;
            }


    ChildItemsDataBind handler:
    protected void RadTreeList2_ChildItemsDataBind(object sender, TreeListChildItemsDataBindEventArgs e)
            {
                string id = e.ParentDataKeyValues["Id"].ToString();
     
                List<SimpleItem> itemList = (List<SimpleItem>)this.Session["MyItems"];
                this.AddAnItem(id, itemList);
                this.Session["MyItems"] = itemList;
                this.RadTreeList2.DataSource = itemList;
            }

    The simple item class... nothing fancy at all...
    [Serializable]
    public class SimpleItem
    {
        public string Id { getset; }
        public string ParentId { getset; }
        public string Name { getset; }
    }

    So that's it. Everything runs as expected until I click on the expander icon for the first item - then it runs through all of the methods but blows up when it tries to render the page with "Object not set to an instance..."

    What am I missing? Seems like I should be pretty close.
    A
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 07 May 2012 Link to this post

    Hi Alex,

    Note that in the ChildItemDataBind event you should set a DataSource using ChildItemsDataSource as it is shown in the online demo below:
    http://demos.telerik.com/aspnet-ajax/treelist/examples/databinding/loadondemand/defaultcs.aspx

    Please follow the approach presented in this example and verify if this works for you.

    Regards,

    Maria Ilieva
    the Telerik team
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
Back to Top