<telerik:RadGrid ID="RadGridExample" runat="server" GridLines="Both" Skin="WebBlue"> <MasterTableView AutoGenerateColumns="false" Name="Main"> <%-- This level holds items of Type1 --%> <Columns> </Columns> <DetailTables> <telerik:GridTableView Name="SubLevel1" ShowHeadersWhenNoRecords="false" AutoGenerateColumns="false"> <%-- This level holds items of Type2 --%> <Columns> </Columns> <DetailTables> <telerik:GridTableView Name="SubLevel2" ShowHeader="false" AutoGenerateColumns="false" > <%-- This level holds items of Type2 --%> <Columns> </Columns> <DetailTables> <telerik:GridTableView Name="SubLevel3" ShowHeader="false" AutoGenerateColumns="false"> <%-- This level holds items of Type2 --%> <Columns> </Columns> <DetailTables> <telerik:GridTableView Name="SubLevel4" ShowHeader="false" AutoGenerateColumns="false"> <%-- This level holds items of Type2 --%> <Columns> </Columns> </telerik:GridTableView> </DetailTables> </telerik:GridTableView> </DetailTables> </telerik:GridTableView> </DetailTables> </telerik:GridTableView> </DetailTables> </MasterTableView> </telerik:RadGrid>protected void Page_Init(object sender, EventArgs e){ IViewContainer container = this.Page as IViewContainer; if (container != null) { container.Register(this); }}IEnumerable<Tuple<Type1,IEnumerable<Tree<Type2>>>>public class Tree<TItem>{ public Tree(TItem rootItem) { root = new TreeNode<TItem>(rootItem); } public Tree(TreeNode<TItem> rootNode) { this.root = rootNode; } private TreeNode<TItem> root; public TreeNode<TItem> Root { get { return root; } }}public class TreeNode<TItem>{ public TreeNode(TItem item) { this.item = item; this.children = new List<TreeNode<TItem>>(); this.isLeaf = true; } public TreeNode(TItem item, bool isLeaf) { this.item = item; this.isLeaf = isLeaf; this.children = new List<TreeNode<TItem>>(); } public TreeNode(TItem node, IEnumerable<TItem> children) { this.item = node; this.children = new List<TreeNode<TItem>>(children.Count()); foreach (var child in children) { this.children.Add(new TreeNode<TItem>(child)); } this.isLeaf = false; } private TItem item; public TItem Item { get { return item;} } private List<TreeNode<TItem>> children; public IEnumerable<TreeNode<TItem>> Children { get { if (isLeaf) throw new InvalidOperationException("Node is set as Leaf so it can't have children"); return children; } } private bool isLeaf; public bool IsLeaf { get { return isLeaf; } set { isLeaf = value; } } public void AddChild(TItem item) { isLeaf = false; children.Add(new TreeNode<TItem>(item)); } public void AddChild(TreeNode<TItem> item) { isLeaf = false; children.Add(item); } public void AddChildren(IEnumerable<TItem> items) { isLeaf = false; foreach (var item in items) { children.Add(new TreeNode<TItem>(item)); } } public void AddChildren(IEnumerable<TreeNode<TItem>> items) { isLeaf = false; foreach (var item in items) { children.Add(item); } }}object parentDataItem = e.DetailTableView.ParentItem.DataItem;if (parentDataItem is Type1){ Type1 fac = parentDataItem as Type1; var tuple = hierarchy.Single(t => t.Item1 == fac); if (tuple.Item2 != null) { var roots = tuple.Item2.Select(tree => tree.Root); //selects IEnumerable<TreeNode<Type2>> e.DetailTableView.DataSource = roots; }}else if (parentDataItem is TreeNode<Type2>){ TreeNode<Type2> node = parentDataItem as TreeNode<Type2>; if (!node.IsLeaf) { e.DetailTableView.DataSource = node.Children; }}


<script type="text/javascript">
function onRowDropping(sender, args) {
if (sender.get_id() == "<%=grdPendingOrders.ClientID %>") {
var node = args.get_destinationHtmlElement();
if (!isChildOf('<%=grdShippedOrders.ClientID %>', node) && !isChildOf('<%=grdPendingOrders.ClientID %>', node)) {
args.set_cancel(true);
}
}
else if (sender.get_id() == "<%=grdShippedOrders.ClientID %>") {
var node = args.get_destinationHtmlElement();
if (!isChildOf('<%=grdPendingOrders.ClientID %>', node) && !isChildOf('<%=grdShippedOrders.ClientID %>', node)) {
args.set_cancel(true);
}
}
else {
var node = args.get_destinationHtmlElement();
if (!isChildOf('trashCan', node)) {
args.set_cancel(true);
}
else {
if (confirm("Are you sure you want to delete this order?"))
args.set_destinationHtmlElement($get('trashCan'));
else
args.set_cancel(true);
}
}
}
function isChildOf(parentId, element) {
while (element) {
if (element.id && element.id.indexOf(parentId) > -1) {
return true;
}
element = element.parentNode;
}
return false;
}
</script>