Search code examples
architecturesilverlight-3.0

Architecting Silverlight 3 applications


I'm bumbling my way through creating a Silverlight 3 application. I need some high level guidance for the following scenario.

I have a page where a user fills out a bunch of information. At the bottom of the page there is basically a submit button.

When clicked, it commits the info to the database (via ria services), and then I need it for forward the user to a new page.

My Submit method basically looks like so:

void Click(object o, eventArgs e) {
    ViewModel.SaveMyStuff();
    this.NavigationService.Navigate(MyUri);
}

Because the SaveMyStuff() method is asynchronous, the Navigate function is run almost immediatly. And it seems, that the commit to the database is never fully completed. Navigating away from the page causes it (and the viewmodel) to be unloaded.

So Basically I don't want the redirect to take place, until after the DB commit has completed, so I'm looking at wiring up event handlers and it's all turning into a bit of a mess. Is there some sort of pattern or best-practice for handling whether or not pages can be navigated away from (and other basic page mechanics)?

I did have some code that was basically:

if (ViewModel.RiaDataContext.IsSubmitting) {
    Thread.Sleep(500);
}

But a.) that seems like an ugly hack, and b.) that condition is never false - seems there might be a bug in Ria Services or similar.


Solution

  • Given that the standard Silverlight model is asynchronous, the best approach here would be to make sure that SaveMyStuff can call you when it's done - at this point you can then navigate away to your next page in that callback.

    this.ViewModel.BeginSaveMyStuff(this.OnSaveDone, null);
    
    private void OnSaveDone(IAsyncResult ar)
    {
        Dispatcher.BeginInvoke(() => this.NavigateToNextPage());
    }
    

    In terms of the RIA Data Services object (inside your ViewModel presumably) it looks like you can do:

    myContext.SubmitChanges(OnSubmitCompleted, null);
    
    private void OnSubmitCompleted(SubmitOperation so)
    {
        if (so.Error != null)
        {
            // Show the error somehow
        }
        else
        {
            // Fire an event, trigger navigation, you decide!
        }
    }