1
votes

I am building my first silverlight application. This application has several forms that allow user to save Customers, Vendors, Staff etc. Each page has one parent usercontrol (with a corresponding viewmodel) and one or more child usercontrols (each with a viewmodel of its own). For example customer form would have Customer usercontrol as the parent and Address Usercontrol, Phone Numbers UserControl as Child usercontrols on the form. Now the parent "Customer" is responsible for ensuring the data is saved for Customer, Address and Phone when the user clicks the Save button. Behind the scenes I could share a datacontext instance between customer, address and phone number viewmodels. So when the Save button is clicked, the customer usercontrol could save data for all three (since its datacontext would have the Address and PhoneNumber entities as well).

What I would like to know how to pass this datacontext from Customer to Address and Phone Number? One way could be to pass datacontext to Address and Phone number view model in their respective constructors but then I would need to ensure the Address and PhoneNumber constructors are called only after Customer viewodel has been created. can there be a better solution? Does MEF offer any better solution?

2

2 Answers

1
votes

You have the power of Silverlight client-side. Meaning: you have statics :-)

The way I did this in our most recent app was to create a ContextCache. Basically, it's a static class that holds all of my RIA contexts for use in any of my ViewModels. Like so:

public static class ContextCache
  {
    private static TicketContext _ticketContext;

    public static TicketContext TicketContext
    {
      get
      {
        if (_ticketContext == null)
          _ticketContext = new TicketContext();

        return _ticketContext;
      }
      private set { _ticketContext = value; }
    }
  }

So, in a ViewModel, you just make a call to ContextCache.TicketContext and you can save changes. This way you can take advantage of all of the state change tracking in RIA and let it handle all the details for you about object persistance (if you've coded your services correctly that is, but that's another story).

0
votes

Perhaps with your architecture a bad solution can be with IsolatedStorageFile which you may simulate ASP.NET's session!

From my understanding, you are trying to overuse the MV-VM pattern in your app! One of the important reason ViewModel came in our life is because of unit testable! If I were you, I would have had a Customer ViewModel and use it in all my child-usercontrols!

Depending on the complexity and isolation if child controls requires it own separate ViewModel, you may consider a parent ViewModel and have properties of the child ViewModel.

public class ParentViewModel : FrameworkElement {

    Child1ViewModel Child1 { get; set; } //Must be a dependency property

    Child1ViewModel Child2 { get; set; } //Must be a dependency property

    ICommand SaveButtonCommand; //Your delegate command of your save button

    public ParentViewModel() {
        Child1 = new Child1ViewModel();
        Child2 = new Child2ViewModel();
    }
}

And you can use this parent view on your Parent XAML

<UserControl.DataContext>
    <ViewModels:ParentViewModels />
</UserControl.DataContext>
<Controls:Child1 DataContext="{Binding Child1}" />
<Controls:Child2 DataContext="{Binding Child2}" />

You also have ICommand SaveButtonCommand in your ParentViewModel and manipulate with the properties in your child ViewModel when clicked!

Hope it helped!