confusing ParentDataKey and DataKey

4 posts, 0 answers
  1. Jayd
    Jayd avatar
    9 posts
    Member since:
    Mar 2011

    Posted 08 Dec 2011 Link to this post

    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.
  2. Andrey
    Admin
    Andrey avatar
    836 posts

    Posted 13 Dec 2011 Link to this post

    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
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Srihari
    Srihari avatar
    2 posts
    Member since:
    Jun 2014

    Posted 30 Aug 2014 Link to this post

    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.
  5. Viktor Tachev
    Admin
    Viktor Tachev avatar
    1488 posts

    Posted 03 Sep 2014 Link to this post

    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.

     
Back to Top