Self Referencing Hierarchy WCF RIA Services - Level Display Problem

8 posts, 0 answers
  1. Shaikh Ahmad
    Shaikh Ahmad avatar
    20 posts
    Member since:
    Oct 2012

    Posted 23 Jul 2010 Link to this post

    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>
  2. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 23 Jul 2010 Link to this post

    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
  3. DevCraft banner
  4. Shaikh Ahmad
    Shaikh Ahmad avatar
    20 posts
    Member since:
    Oct 2012

    Posted 23 Jul 2010 Link to this post

    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
  5. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 27 Jul 2010 Link to this post

    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
  6. Waleed Seada
    Waleed Seada avatar
    241 posts
    Member since:
    May 2006

    Posted 21 Feb 2011 Link to this post

    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
  7. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 24 Feb 2011 Link to this post

    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!
  8. Alex
    Alex avatar
    7 posts
    Member since:
    Nov 2011

    Posted 06 Apr 2012 Link to this post

    The example you provide is very usefull but do you have any similar example using OpenAccess ORM ?
  9. Ivailo
    Admin
    Ivailo avatar
    318 posts

    Posted 10 Apr 2012 Link to this post

    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 >>
Back to Top
DevCraft banner