Reputation: 131
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
Upvotes: 2
Views: 7076
Reputation: 131
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()
{
}
}
}
Upvotes: 4
Reputation: 3453
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 ?
Upvotes: 2