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

confusing ParentDataKey and DataKey

3 Answers 142 Views
TreeList
This is a migrated thread and some comments may be shown as answers.
Jayd
Top achievements
Rank 1
Jayd asked on 08 Dec 2011, 05:57 PM
I have a RadTreeView where the nesting is not happening how I'd like.  I think it is confusing values from the ParentDataKey and DataKey.  I am loading data from two tables - ApplicationParent and Application.  The Application table has a ParentId column that is a foreign key to ApplicationParent.

There is one record that I'm having trouble with.  See the attached screenshot "treelist data.jpg".  There is an app with a ParentID of 100.  There also exists an Application with an AppId of 100 and an ApplicationParent record with a ParentId of 100.  In the UI, the nesting occurs as shown in the attached screenshots "treelist ui 1.jpg" and "treelist ui 2.jpg".  What I want is for the application "UBH PIF Tracking" to be nested underneath the parent app of the same name.

Here is my code for the TreeList markup and for loading the data:

<telerik:RadTreeList ID="lstApplications" runat="server" AllowSorting="True"
                    ParentDataKeyNames="ParentID" DataKeyNames="AppID"
                    OnNeedDataSource="lstApplications_NeedDataSource"                                         
                    AutoGenerateColumns="False" AllowPaging="True"
                    PageSize="15" TabIndex="3" >
                    <clientsettings>                                               
                        <Selecting AllowItemSelection="True" />
                        <ClientEvents OnItemClick="OnItemClick" OnItemDblClick="OnItemDblClick" />                       
                        <selecting allowitemselection="True" />
                    </clientsettings>
                    <Columns>
                        <telerik:TreeListBoundColumn DataField="AppID" HeaderText="AppID"
                            UniqueName="AppID" Visible="false" ReadOnly="True" />
                        <telerik:TreeListBoundColumn DataField="Name" HeaderText="Application"
                            ItemStyle-Width="20%" UniqueName="Name" ReadOnly="True">
                            <HeaderStyle Width="20%" />
                            <ItemStyle Width="20%" />
                        </telerik:TreeListBoundColumn>
                        <telerik:TreeListBoundColumn DataField="Description" HeaderText="Description"
                            UniqueName="Description" ReadOnly="True" />                           
                    </Columns>
                </telerik:RadTreeList>


public class MyData
    {
        public static List<MyItem> GetData(String prefixText)
        {
            var mergedList = GetParentData(prefixText).Union(GetChildData(prefixText)).ToList();
            return mergedList;
 
            //return GetChildData(prefixText);
        }
 
        public static List<MyItem> GetParentData(String prefixText)
        {
            SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DataAccess.Properties.Settings.SecureConnectionString"].ConnectionString);
            SqlCommand cmd = new SqlCommand("SelApplicationsParent", cn);
            cmd.CommandType = CommandType.StoredProcedure;
 
            if (!prefixText.Equals(String.Empty))
            {
                cmd.Parameters.AddWithValue("nrows", 30);                   //Set results limit to prevent typing lag.
                cmd.Parameters.AddWithValue("term", ("%" + prefixText + "%"));    //Set filter by name
            }
 
            List<MyItem> list = new List<MyItem>();
            cn.Open();
 
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    string AppID = dr["ParentID"].ToString();
                    string ParentID = ""; //dr["ParentID"].ToString();
                    string Name = dr["Name"].ToString();
                    string Description = dr["Description"].ToString();
 
                    list.Add(new MyItem(AppID, Name, Description, ParentID));
                }
            }
 
            dr.Close();
 
            return list;
        }
 
        public static List<MyItem> GetChildData(String prefixText)
        {
            SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DataAccess.Properties.Settings.SecureConnectionString"].ConnectionString);
            SqlCommand cmd = new SqlCommand("SelApplicationsChild", cn);
            cmd.CommandType = CommandType.StoredProcedure;
 
            if (!prefixText.Equals(String.Empty))
            {
                cmd.Parameters.AddWithValue("NRows", 30); //Set results limit to prevent typing lag.
                cmd.Parameters.AddWithValue("Parent", ("%" + prefixText + "%"));
            }
 
            List<MyItem> list = new List<MyItem>();
            cn.Open();
 
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    string AppID = dr["AppID"].ToString();
                    string ParentID = dr["ParentID"].ToString();
                    string Name = dr["Name"].ToString();
                    string Description = dr["Description"].ToString();
 
                    list.Add(new MyItem(AppID, Name, Description, ParentID));
                }
            }
 
            dr.Close();
 
            return list;
        }
    }
 
    public class MyItem
    {
        public string AppID { get; set; }
        public string ParentID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
 
        public MyItem(string appID, string name, string description, string parentID)
        {
            AppID = appID;
            ParentID = parentID;
            Name = name;
            Description = description;
        }
    }
 
 protected void lstApplications_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
    {
        lstApplications.DataSource = MyData.GetData(txtFilter.Text);
    }


How do you suggest I solve this problem?  Right now my only idea is to modify the DB to ensure that there are no ApplicationParents that have a ParentId that is equal to an Application.AppId.

3 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 13 Dec 2011, 04:29 PM
Hello Jayd,

The problem with your approach is the data-binding that you are using. TreeList is a control that displays self-reference hierarchical data. Thus you need only one DataTable of data. And based of the data in that DataTable RadTreeList will generate the appropriate structure. Here comes the problem with your code, you have two different tables and you are making union of them before attach it as a datasource.

The ParentDataKeyNames and DataKeyNames are just for the same purpose. TreeList uses them to split the table and build the hierarchy for you.

So my suggestion to you is to leave just one method which returns all the data in one table and leave the rest to the RadTreeList. For similar data structure you could refer to the Employees table of the Northwind database.

For guidance with RadTreeList you could use this online demo which is implementing similar approach.

If you need to display data from two or more tables it is better you use RadGrid hierarchy. Online demo for RadGrid hierarchy could be seen here.

All the best,
Andrey
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
0
Srihari
Top achievements
Rank 1
answered on 30 Aug 2014, 08:21 AM
Hi, 
I am using a rad treelist as nested in a radgrid. There are client side click events for the radgrid and treelist. But when i click on the treelist the event for the radgrid is fired. Then i am not getting the treelist datakey value. I have set the clientdatakeyname for treelist. Also when I execute the "Id.ClientId" command to get the treelist i get the error that id does not exist in current context.
0
Viktor Tachev
Telerik team
answered on 03 Sep 2014, 12:44 PM
Hello Srihari,

The reason for the described behavior is the "bubbling" of the events. If a RadTreeList is nested in a RadGrid control first the client-side event for the RadTreeList is triggered and then the client event for the RadGrid. If you would like to execute only one event you would need to add additional logic that cancels the event that should not be executed.

If you would like additional information on event bubbling you would find this article interesting.

Regards,
Viktor Tachev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
TreeList
Asked by
Jayd
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Srihari
Top achievements
Rank 1
Viktor Tachev
Telerik team
Share this question
or