This is a migrated thread and some comments may be shown as answers.

Need help - new to RadTreeList control

2 Answers 103 Views
TreeList
This is a migrated thread and some comments may be shown as answers.
Alex
Top achievements
Rank 1
Alex asked on 02 May 2012, 06:26 PM
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 Answers, 1 is accepted

Sort by
0
Alex
Top achievements
Rank 1
answered on 02 May 2012, 10:01 PM
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
0
Maria Ilieva
Telerik team
answered on 07 May 2012, 09:20 AM

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.
Tags
TreeList
Asked by
Alex
Top achievements
Rank 1
Answers by
Alex
Top achievements
Rank 1
Maria Ilieva
Telerik team
Share this question
or