Self-referencing grid with missing parent items.

6 posts, 0 answers
  1. Grzegorz
    Grzegorz avatar
    5 posts
    Member since:
    Feb 2013

    Posted 11 Apr 2017 Link to this post

    Hi.

     

    I'm facing and issue with displaying hierarchical data (self-referencing) in grid when missing parent items in data source - only part of data is displayed.

     

    1. Add grid to form

    1.var grid = new RadGridView {Dock = DockStyle.Fill};
    2.this.Controls.Add(grid);
    3.grid.Columns.Add("cName","Name","Name"); //Dummy column displaying Name

     

    2. Setup self-referencing

    1.var col1 = new GridViewTextBoxColumn("hiddenColumnId", "Id");
    2.var col2 = new GridViewTextBoxColumn("hiddenColumnParentId", "ParentId");
    3.grid.MasterTemplate.Columns.Add(col1);
    4.grid.MasterTemplate.Columns.Add(col2);
    5.grid.Columns["hiddenColumnId"].IsVisible = false;
    6.grid.Columns["hiddenColumnParentId"].IsVisible = false;
    7.grid.Relations.AddSelfReference(grid.MasterTemplate, "hiddenColumnId", "hiddenColumnParentId");

     

    3. Create dummy data type

    01.class Item
    02.{
    03.    public Item(int id, string name, int? parentId = null)
    04.    {
    05.        Id = id;
    06.        Name = name;
    07.        ParentId = parentId;
    08.    }
    09. 
    10.    public int Id { get; set; }
    11.    public string Name { get; set; }
    12.    public int? ParentId { get; set; }
    13.}

     

    4. Add new data source

    01.var items = new List<Item>
    02.{
    03.    new Item(1,"1"),
    04.    new Item(2,"1.1",1),
    05.    new Item(3,"1.2",1),
    06.    new Item(7,"1.2.1",3),
    07.    new Item(4,"2"),
    08.    new Item(5,"2.1",4),
    09.    new Item(6,"2.2",4)
    10.};
    11.grid.DataSource = items;

     

    And as expected a correct tree structure is displayed

    1.1
    2.-1.1
    3.-1.2
    4.--1.2.1
    5.2
    6.-2.1
    7.-2.2

     

     

    However in my case due to busines logic I have only a subset of data - all except item "1" and "2".

    Instead of ex

    1.1.1
    2.1.2
    3.-1.2.1
    4.2.1
    5.2.2

     

    I can see only children of first missing parent item. Although the number of rows is matching correct total number of item to be displayed (5) only part of items are visible (3).

    1.1.1
    2.1.2
    3.-1.2.1

     

     

    As a workaroud I can modify data source and remove parent assignement from objects if parent is missing in data source either on data preparation or DataBindingComplete event.

    01.private void Grid_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
    02. {
    03.     var grid = sender as RadGridView;
    04.      
    05.    // Get existing items
    06.     var ids = new List<object>();
    07.     foreach (var id in grid.Columns["hiddenColumnId"].DistinctValues)
    08.     {
    09.         ids.Add(id);
    10.     }
    11. 
    12.    // Remove missing parents
    13.    foreach (var row in grid.Rows)
    14.    {
    15.        var parentId = row.Cells["hiddenColumnParentId"].Value;
    16.        if (!ids.Contains(parentId))
    17.            row.Cells["hiddenColumnParentId"].Value = null;
    18.    }
    19.}

     

     

    However this solution is not suitable, because it is modifying data providing inconsistant state - using that data in code I may falsly assume that the item does not have a parent while it has.

     

    Any ideas how to solve this issue?

     

    Regargs
    Greg

  2. Hristo
    Admin
    Hristo avatar
    1510 posts

    Posted 11 Apr 2017 Link to this post

    Hi Grzegorz,

    Thank you for writing.

    Creating items with a parent id which is not present in the grid is not supported. In this kind of setup, the grid will try to create a second root node which is not possible. 

    If it fits your local setup, please do not set parents which are not added to the grid. In this case, you can also set them to null
    var items = new List<Item>
    {
        //new Item(1, "1"),
        new Item(2, "1.1"),
        new Item(3, "1.2"),
        new Item(7, "1.2.1", 3),
        //new Item(4, "2"),
        new Item(5, "2.1"),
        new Item(6, "2.2")
    };
    Alternatively: 
    var items = new List<Item>
    {
        //new Item(1, "1"),
        new Item(2, "1.1", null),
        new Item(3, "1.2", null),
        new Item(7, "1.2.1", 3),
        //new Item(4, "2"),
        new Item(5, "2.1", null),
        new Item(6, "2.2", null)
    };

    I am also sending you a screenshot showing the result on my end.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Fanie
    Fanie avatar
    12 posts
    Member since:
    Apr 2016

    Posted 24 Oct 2018 Link to this post

    I've got a similar issue with the parent being missing.  Is there an event that gets triggered when there is no matching parent-child, which I can use to create the parent in the binding datasource?
  4. Hristo
    Admin
    Hristo avatar
    1510 posts

    Posted 26 Oct 2018 Link to this post

    Hello Fanie,

    Thank you for writing.

    There is no event in the grid to allow such a behavior. The self-reference hierarchy is built extracting the items in the data source and it is required that all of the of the object Ids be unique. Each object should also have a defined parent.

    Let me know if you have other questions.
    Regards,
    Hristo
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  5. Christian
    Christian avatar
    44 posts
    Member since:
    May 2012

    Posted 29 May 2019 in reply to Hristo Link to this post

    Is there any change/update on this?

    Or is there any way to load the complete self-referencing but hide the first n levels in the grid?

    The problem is, I can't change the object/structure because it comes from a 3rd-party lib. 

  6. Hristo
    Admin
    Hristo avatar
    1510 posts

    Posted 30 May 2019 Link to this post

    Hi Christian,

    As modifying the object structure is not an option, a possible solution is to load the complete hierarchy an hide particular parent nodes. The IsVisible property of the row, however, is not suitable in this case as it will also hide the self-referenced child rows. That is why it will be necessary to work with the MaxHeight property of the row: 
    this.radGridView1.Rows[0].MaxHeight = 1;

    I am also attaching a short video showing the result on my end.

    Regards,
    Hristo
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top