How to deal with parent/child on same SL page

Aug 11, 2011 at 10:34 PM
Edited Aug 11, 2011 at 10:43 PM

Hi Tony

I need to extend one of my application's pages (which currently just edits a single entity as ViewModelDetailBase) with a comments feature. A new comment should be able to be saved at the same time as my main entity, and I also need to display a list of comments. In the database I have a dedicated comments table and the primary key of my main entity is a foreign key in the comments table. It seems like I need to display two views on the same page (so presumably two UserControls linked to matching ViewModels which communicate?), however although this might take care of displaying my main entity and associated comments, I still need a way to edit and save a comment as part of the main entity. Any thoughts on how to tackle this one?

You can see the sort of thing I'm tryig to achieve here, where typing in the comment box and then clicking Update saves any changes to the bug and adds the new comment.

I gather from FB that you've just undergone eye surgery, and I do hope you are on the mend and feeling better. We've been missing you round here over the past few days!

Cheers - Graham

Coordinator
Aug 12, 2011 at 12:11 PM

Hi Graham,

Yes, I'm recovering from surgery to replace the lens in my right eye with a new lens.  I'm still in the early stages, but so far I very much like the outcome.  I'm learning to use the magnification feature on OS Lion. ;-)

I assume your app is using WCF RIA Services, in which case persisting updates is relatively easy.  For an example, take a look at Part 3 of the Main sample in the toolkit.  There you'll find a SaveChanges method in the ProductListServiceAgent.

public void SaveChanges(Action<Exception> completed)
{
    // See if any products have changed
    if (domainContext.Products.HasChanges)
    {
        // Submit bulk update
        domainContext.SubmitChanges(submitOp =>
            {
                // Declare error
                Exception error = null;

                // Set error or result
                if (submitOp.HasError)
                {
                    error = submitOp.Error;
                }

                // Invoke completion callback
                completed(error);
            }, null);
    }
}

What this does is do a batch save of all the inserts, updated and deletes that have taken place since the last save.  All the updates take place in a single transaction on the server-side.  RIA Services accomplishes this with good old change-tracking.  The nice thing is that his takes place also for object hierarchies.  So all your inserted, updated and deleted Comment entities will also be persisted.

Hope this helps!

Cheers,

Tony

Aug 12, 2011 at 2:54 PM

Hi Tony

Thanks for this and glad to hear you're doing well after the surgery.

Your reply made me realise that I needed to regenerate my DomainService classes - I've done that and my main entity now has a collection of Comments. However, this leaves me wondering:

  • How do I refer to the comments collection in the VM? I can get to base.Model.Comments but after that the trail goes cold as there is no indexer to get to an individual comment. Do I manually need to craete an ObservableCollection of comments in the VM?
  • Similarly, how do I refer to the properties of a comment in the View when I'm binding? Clearly not Model.Comments.SomeProperty...

Thanks!

Cheers - Graham

 

Coordinator
Aug 13, 2011 at 10:18 PM

Hi Graham,

How you reference the comments depends on what you want to do with them. If you want to add and remove comments and have a control in the View (such as a combo box or list box) updated, then you would be best to put a property on the View for Comments and make that an ObservableCollection, passing base.Model.Comments to the ctor.  Because Comments is a collection, it has an indexer and you can also use Linq to query it.  Most of the time, however, you would simply bind to the Comments property when you set the ItemsSource of a list control.  If you want to reference properties of a Comment in each item of the list control, set the ItemTemplate of the control to a DataTemplate.

Cheers,

Tony