This is a migrated thread and some comments may be shown as answers.

Self Referencing Hierarchy WCF RIA Services - Level Display Problem

7 Answers 269 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Shaikh Ahmad
Top achievements
Rank 1
Shaikh Ahmad asked on 23 Jul 2010, 03:51 PM
Hello,

I'm having problems in displaying a self referencing hierarchy using the radtreeview. The parent and child node appears on the same level. Please see the attached picture. I'm using the WCF RIA Services as the data provider. The context tree will load once the Id of a Paper is retrieved. I've tried following the self referencing guide in the blog but i can't seem to assign the DataContext to my EntityCollection. Is there any other way to do this? Here's my code.

DomainService
public IQueryable<ContextTreeDto> GetContextTreeByPaperId(Guid Id)
        {
            var s = GetSession();
            var paper = s.Get<Paper>(Id);
            var tree = from context in paper.ContextRoot.Children
                       orderby context.Order
                       select new ContextTreeDto(context);
            return tree.AsQueryable();
        }

DtoClass
public class ContextTreeDto : BaseDto
    {
        public string Name { get; set; }
        public Guid PaperId { get; set; }
        public string PaperCode { get; set; }
        public Guid ParentId { get; set; }
        public string ParentText { get; set; }
        [Include]
        [Association("ContextChild", "Id", "ParentId")]
        public IEnumerable<ContextTreeDto> Children { get; set; }

        public ContextTreeDto()
        {
        }

        public ContextTreeDto(TreeNode node)
        {
            this.Id = node.Id;
            this.Name = node.Name;
            this.ParentId = node.Parent.Id;
            this.ParentText = node.Parent.Name;
            this.Children = from c in node.Children
                            orderby c.Order
                            select new ContextTreeDto(c);
        }
}

Code Behind
void LoadContextTree(Guid id)
        {
            LoadOperation loadContextTree = _ctxMetadata.Load(_ctxMetadata.GetContextTreeByPaperIdQuery(id));
            loadContextTree.Completed += new EventHandler(loadContextTree_Completed);
        }

        void loadContextTree_Completed(object sender, EventArgs e)
        {
            TreeContexts.ItemsSource = _ctxMetadata.ContextTreeDtos;
        }

XAML
<telerik:HierarchicalDataTemplate x:Key="ContextTemplate" ItemsSource="{Binding Converter={StaticResource HierarchyConverter}}">
                <TextBlock Text="{Binding Name}" />
            </telerik:HierarchicalDataTemplate>

<telerikNavigation:RadTreeView x:Name="TreeContexts" BorderThickness="0"
                                        ExpanderStyle="{StaticResource ExpanderStyle}"
                                        SelectionChanged="TreeContexts_SelectionChanged"
                                        ItemTemplate="{StaticResource ContextTemplate}">
                                    </telerikNavigation:RadTreeView>

7 Answers, 1 is accepted

Sort by
0
Tina Stancheva
Telerik team
answered on 23 Jul 2010, 04:44 PM
Hi Shaikh Ahmad,

Please find attached a sample project illustrating how to populate RadTreeView with self-referencing data using RIA Services.

I hope it helps. Let us know if you need more info.

Best wishes,
Tina Stancheva
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Shaikh Ahmad
Top achievements
Rank 1
answered on 23 Jul 2010, 05:49 PM
Hello Tina,

Thanks for the quick response. 
First - your solution is using load-on-demand. Is this compulsory?
Second - your solution is using LoadOperation Entities which is read-only and there is no built in INotifyPropertyChanged. Can you show me how to implement this using the EntityCollection?
Third - Can you elaborate more on the ItemPrepared event?

Regards,
Shaikh
0
Tina Stancheva
Telerik team
answered on 27 Jul 2010, 05:35 PM
Hello Shaikh Ahmad,

I'll get straight to your questions:

1. No, you don't have to use LoadOnDemand feature at all costs. You can instead load all items and set only those with ParentId=null as an ItemsSource of the RadTreeView, like so:
void TreeViewPage_Loaded(object sender, RoutedEventArgs e)
{
    LoadOperation operation = context.Load(context.GetMyDataTablesQuery());
    operation.Completed += new EventHandler(operation_Completed);
}
 
void operation_Completed(object sender, EventArgs e)
{
    this.myTreeView.ItemsSource = context.MyDataTables.Where(i => i.ParentID == null);
}
Also, when using this approach you should keep in mind that in order to include the Children collection to the loaded collection of items, you need to add the Include attribute to the Children collection in the DomainService metadata. This attribute indicates that the entity association it is applied to should be part of any code generated client entities.
[MetadataTypeAttribute(typeof(MyDataTable.MyDataTableMetadata))]
public partial class MyDataTable
{
    // This class allows you to attach custom attributes to properties
    // of the MyDataTable class.
    ...
    internal sealed class MyDataTableMetadata
    {
 
    // Metadata classes are not meant to be instantiated.
    private MyDataTableMetadata()
    {
    }
 
    [Include("Count","ChildrenCount")]
    [Include]
    public IList<MyDataTable> Children { get; set; }
 
    public int ID { get; set; }
 
    public int ParentID { get; set; }
 
    public string Text { get; set; }
    }
 
}
However, it is recommended to use the LoadOnDemand feature when loading a significant number of items in order to optimize the RadTreeView performance.

2. Instead of the LoadOperation Entities collection, you can use the context.MyDataTables as shown above. Also, another approach is to use the Entities collection, but wrap it in an ObservableCollection, for example:
void TreeViewPage_Loaded(object sender, RoutedEventArgs e)
{
    LoadOperation operation = context.Load(context.GetMyDataTablesQuery());
    operation.Completed += new EventHandler(operation_Completed);
}
 
void operation_Completed(object sender, EventArgs e)
{
    ObservableCollection<Entity> wrapCollection = new ObservableCollection<Entity>((sender as LoadOperation).Entities);
    this.myTreeView.ItemsSource = wrapCollection;
}

3. More information about the ItemPrepared() event you can find here.

I also modified the example to illustrate an approach without the RadTreeView LoadOnDemand feature. Take a look at it and the info and let me know if I can further assist you.

All the best,
Tina Stancheva
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Waleed Seada
Top achievements
Rank 2
answered on 21 Feb 2011, 07:42 PM
Dear All,

I found this thread very usefull to me... I have a question here ..

How can I bind the LoadOnDemand to Command as so : LoadOnDemand="{Binding ItemExpandedCommand}" where is command is define in my VM.

Best regards
Waleed
0
Petar Mladenov
Telerik team
answered on 24 Feb 2011, 06:27 PM
Hi Waleed Seada,

Please let us know if the answer here satisfies you or not. Feel free to ask if you need further assistance. You could provide a sample if things are getting too complex to explain. This way we could advice you better.

Regards,
Petar Mladenov
the Telerik team
Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
0
Alex
Top achievements
Rank 1
answered on 06 Apr 2012, 01:13 PM
The example you provide is very usefull but do you have any similar example using OpenAccess ORM ?
0
Ivailo
Telerik team
answered on 10 Apr 2012, 04:20 PM
Hi Alex,

Thank you for your interest in OpenAccess ORM.

While there isn't such sample with OpenAccess, you can convert your edmx model to OpenAccess Domain Model using the Convert from Entity Framework wizard.

OpenAccess ORM also offers a RIA wizard, generating the service for your convenience. You can use it or just create the service definition manually (in case of the specified sample - just use the same infrastructure). The wizard supports Silverlight 3 and 4, but doesn't support Silverlight 5 yet.

In general you can download the OpenAccess SDK if you need sample projects - we do have a Silverlight example there. 

Let us know if you have any questions or you need assistance in using OpenAccess ORM in Silverlight applications. You are welcome to start a separate thread in the OpenAccess forums for that purpose.

Greetings,
Ivailo
the Telerik team
Telerik OpenAccess ORM Q1 2012 release is here! Check out what's new or download a free trial >>
Tags
TreeView
Asked by
Shaikh Ahmad
Top achievements
Rank 1
Answers by
Tina Stancheva
Telerik team
Shaikh Ahmad
Top achievements
Rank 1
Waleed Seada
Top achievements
Rank 2
Petar Mladenov
Telerik team
Alex
Top achievements
Rank 1
Ivailo
Telerik team
Share this question
or