How to use DomainContext.Load to populate the properties of my ViewModel?

I have a Silverlight page that retrieves its data from a view model class that integrates some data from various RIA service domain services.

Ideally, I would like the page to be able to bind its controls to the properties of the view model object, but since DomainContext.Load makes an asynchronous request, the data is not available when the page loads.

My Silverlight page has the following XAML:

 <navigation:Page x:Class="Demo.UI.Pages.WidgetPage" // the usual xmlns stuff here... xmlns:local="clr-namespace:Demo.UI.Pages" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DataContext="{d:DesignInstance Type=local:WidgetPageModel, IsDesignTimeCreatable=False}" d:DesignWidth="640" d:DesignHeight="480" Title="Widget Page"> <Canvas x:Name="LayoutRoot"> <ListBox ItemsSource="{Binding RedWidgets}" Width="150" Height="500" /> </Canvas> </navigation:Page> 

My ViewModel looks like this:

 public class WidgetPageModel { private WidgetDomainContext WidgetContext { get; set; } public WidgetPageModel() { this.WidgetContext = new WidgetDomainContext(); WidgetContext.Load(WidgetContext.GetAllWidgetsQuery(), false); } public IEnumerable<Widget> RedWidgets { get { return this.WidgetContext.Widgets.Where(w => w.Colour == "Red"); } } } 

I think this approach should be fundamentally wrong, because the asynchronous nature of Load means that the widget list does not necessarily populate when the ListBox data is bound. (The breakpoint in my repository indicates that the code to fill in the collection is executing, but only after the page is displayed.)

Can someone please show me the correct way to do this?

+7
silverlight viewmodel mvvm wcf-ria-services
source share
1 answer

The missing part of the puzzle is that I needed to create events when the properties changed.

My updated ViewModel looks like this:

 public class WidgetPageModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private WidgetDomainContext WidgetContext { get; set; } public WidgetPageModel() { this.WidgetContext = new WidgetDomainContext(); WidgetContext.Load(WidgetContext.GetAllWidgetsQuery(), (result) => { this.RedWidgets = this.WidgetContext.Widgets.Where(w => w.Colour == "Red"); }, null); } private IEnumerable<Widget> _redWidgets; public IEnumerable<Widget> RedWidgets { get { return _redWidgets; } set { if(value != _redWidgets) { _redWidgets = value; RaisePropertyChanged("RedWidgets"); } } } } 

The controls associated with these properties are updated when a property change event occurs.

+4
source share

All Articles