У меня есть страница Silverlight, которая получает ее данные из класса модели представления, который агрегировал некоторые данные из различного (сервисы RIA) доменные сервисы.
Идеально я хотел бы, чтобы страница смогла к привязке данных свои средства управления к свойствам объекта модели представления, но потому что DomainContext.Load
выполняет запрос асинхронно, данные не доступны, когда страница загружается.
Страница My Silverlight имеет следующий 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>
Мой ViewModel похож на это:
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");
}
}
}
Я думаю, что этот подход должен быть существенно неправильным потому что асинхронная природа Load
средства, что список виджета не обязательно заполняется когда привязки данных ListBox. (Точка останова в моем репозитории показывает, что код для заполнения к набору выполняется, но только после рендеринга страницы.)
Кто-то может показать мне правильный способ сделать это?
Недостаток головоломки заключается в том, что мне нужно было вызывать события при изменении свойств.
Моя обновленная ViewModel выглядит следующим образом:
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");
}
}
}
}
Элементы управления, привязанные к этим свойствам, обновляются при возникновении события изменения свойства.