7

Tengo una página de Silverlight que obtiene sus datos de una clase de modelo de vista que agrega algunos datos de varios servicios de dominio (servicios de RIA).¿Cómo uso DomainContext.Load para rellenar las propiedades de mi ViewModel?

Idealmente me gustaría que la página pueda enlazar sus controles a las propiedades del objeto del modelo de vista, pero como DomainContext.Load ejecuta una consulta de forma asincrónica, los datos no están disponibles cuando se carga la página.

Mi página Silverlight tiene la siguiente 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> 

Mi modelo de vista se parece a esto:

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"); 
     } 
    } 
} 

Creo que este enfoque debe ser fundamentalmente equivocada porque la naturaleza asíncrona de Load significa que el widget la lista no se rellena necesariamente cuando se vinculan los datos de ListBox. (Un punto de interrupción en mi repositorio muestra que el código para poblar a la colección se está ejecutando, pero solo después de que se renderice la página.)

¿Puede alguien mostrarme la forma correcta de hacerlo?

Respuesta

4

La pieza que faltaba en el rompecabezas es que necesitaba generar eventos cuando las propiedades cambiaban.

Mi modelo de vista actualizado es el siguiente:

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"); 
      } 
     } 
    } 
} 

Los controles enlazados a estas propiedades se actualizan cuando se activa el evento de cambio de propiedad.

Cuestiones relacionadas