2

Suppose i have

class Person
{
    public int Id {get;set;}
    public string Name {get;set;}
    public List<Person> All {get;set;}

    public Person()
    {
    }

    public List<Person> GetAll()
    {
        //fills the list with person and returns
    }
}

and that i have:

class Address 
{
    public int PersonId {get;set;}
    public string theAddress {get;set;}
    public List<Address> All {get;set;}

    //constructor, etc

    public List<Address> GetAll()
    {
        //fills the address list and returns
    }
}

What im trying to do is exactly the following:

//filling the maintemplate with data
radGridView1.DataMember = "Person";
radGridView1.DataSource = new Person().GetAll();     

//address template, the child one
GridViewTemplate template = new GridViewTemplate();
template.DataSource = new Address().GetAll();
template.DataMember = "Address";
radGridView1.MasterTemplate.Templates.Add(template);

//now the relation between those 2 classes

GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate);
relation.ChildTemplate = template;
relation.RelationName = "PersonAddress"; //just a name
relation.ParentColumnNames.Add("Id"); //field to be "joined" to create the relation
relation.ChildColumnNames.Add("PersonId"); //same as above
radGridView1.Relations.Add(relation);

and what i get is exactly a gridview with a "+" sign by the side of each Person The problem is, the "child" grid is EMPTY, and if i try to add data (its, by default, allowed with an empty constructor in the class) i throw an NullArgumentException

Any ideas? im almost giving up. My problem is: i use custom objects on all projects, its not like "yo use datasets, its ready to use etc", i know that, but i would like to know if there's a way to use CUSTOM OBJECTS, or if im done and should try datasets...

Thanks guys

Kris Ivanov
  • 10,476
  • 1
  • 24
  • 35
Edward
  • 131
  • 2
  • 11
  • assuming you have seen the demos for hierarchical grids and also read the documentation for the RadGrid, however there is some straight forward details here: http://www.telerik.com/help/aspnet-ajax/grdunderstandinghierarchy.html – Kris Ivanov Feb 17 '11 at 02:42
  • Well, you pointed me to a link that explains asp.net grid. I'm assuming they're not of the same type, am i right? if i'm wrong i beg your pardon, but im totally new to Paid components. Its usefull but at first time, you get lost (as i am). And Edit: I just tested with a dataset + 2 table adapters pointing to 2 tables, guess what? the same code worked as a charm (but using datasets). Ill read your link again and see if i can get something usefull from that. Many thanks – Edward Feb 17 '11 at 03:34
  • after looking at this link http://documentation.devexpress.com/#WindowsForms/CustomDocument5496 i just realized i should migrate to DevExpress, cause they just solved my problem the way i first try to display a master-detail using Telerik's grid. When i downloaded their product, i was expecting a "automatic" recognition of an association inside my list, and that didnt happened. Since im still evaluating their product, im gonna quit and go Dev. Thanks ivanov, for your help and time. – Edward Feb 17 '11 at 04:03

2 Answers2

4

It looks like you are using the WinForms implementation. If that's right, then this works for me fine. Please give this a go

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls.UI;

namespace RadGridView_Hierarchy_CS
{
    public partial class Form1 : Form
    {

        private List<Person> people = new List<Person>();
        private List<Address> addresses = new List<Address>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FillPeople();
            FillAddresses();

            radGridView1.DataSource = people;

            GridViewTemplate template = new GridViewTemplate();
            template.DataSource = addresses;
            radGridView1.MasterTemplate.Templates.Add(template);

            GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate);
            relation.ChildTemplate = template;
            relation.RelationName = "PersonAddress";
            relation.ParentColumnNames.Add("Id");
            relation.ChildColumnNames.Add("PersonId");
            radGridView1.Relations.Add(relation);

        }

        private void FillPeople()
        {
            Person richard = new Person();
            richard.Name = "Richard";
            richard.Id = 1;
            people.Add(richard);
            Person bob = new Person();
            bob.Name = "Bob";
            bob.Id = 2;
            people.Add(richard);
            Person mike = new Person();
            mike.Name = "Mike";
            mike.Id = 3;
            people.Add(mike);
        }

        private void FillAddresses()
        {
            Address house1 = new Address();
            house1.PersonId = 1;
            house1.Id = 1;
            house1.theAddress = "1 The Mews";
            addresses.Add(house1);
            Address house2 = new Address();
            house2.PersonId = 2;
            house2.Id = 2;
            house2.theAddress = "2 The Mews";
            addresses.Add(house2);
        }    
    }

    class Person 
    {     
        public int Id {get;set;}     
        public string Name {get;set;}     


        public Person()     
        { 
        }              
    }

    class Address  
    {
        public int Id { get; set; }   
        public int PersonId {get;set;}    
        public string theAddress {get;set;}     

        public Address()
        { 
        }
    }
}
Nadav Ben-Gal
  • 549
  • 3
  • 13
  • I appreciate your answer Richard, and i'm gonna accept it as answer since i already chose whose ill buy my components. – Edward Feb 17 '11 at 18:30
2

stumbled over you post when searching for a solution to this, so ill add my solution in case someone needs it ... ( using version Q1 2011 ).

in some initialisation method of your UC/Grid you could do something like

     //setup the template 
     GridViewTemplate subtemplate = new GridViewTemplate();
     subtemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
     subtemplate.EnableFiltering = false;
     subtemplate.EnableGrouping = false;
     subtemplate.AutoGenerateColumns = false;

     //define / add the cols
     GridViewTextBoxColumn atextcol = new GridViewTextBoxColumn("Name");
     //further properties of atextcol

      //add the cols to the template
      subtemplate.Columns.Add(atextcol);

      //add the template to the grid
      thegrid.Templates.Add(subtemplate);

     //add a HierarchyDataProvider && subscribe to the RowSourceNeeded-Event
      subtemplate.HierarchyDataProvider = new GridViewEventDataProvider(subtemplate);

      thegrid.RowSourceNeeded += new GridViewRowSourceNeededEventHandler(thegrid_RowSourceNeeded);

then, in the eventhandler fill the row/rows

protected void thegrid_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e)
        {
            e.Template.Rows.Clear();
            patentdata cparent = e.ParentRow.DataBoundItem as patentdata;

            foreach (subdataobject sub in parentdata.subs)
            {
                GridViewRowInfo row = e.Template.Rows.NewRow();
                row.Tag = sub;
                row.Cells["Name"].Value = sub.Name;
                e.SourceCollection.Add(row);
            }
        }

so, that would be it. critics ?

womd
  • 3,077
  • 26
  • 20