Silverlight 4 + WCF与MVVM:集合不被填充的原因
本文关键字:填充 集合 WCF MVVM Silverlight | 更新日期: 2023-09-27 18:03:20
让我先展示一下代码。
WCF serviceccontract函数:
public List<VenueData> GetVenues()
{
List<VenueData> listOfVenues = new List<VenueData>();
string connString = @"....";
DataContext dc = new DataContext(connString);
Table<VenueData> venues = dc.GetTable<VenueData>();
listOfVenues = (from v in venues
select v).ToList();
return listOfVenues;
}
VenueViewModel.cs
public class VenueViewModel : ViewModelBase
{
private VenueData _venue;
private ObservableCollection<VenueData> _venues = new ObservableCollection<VenueData>();
public VenueData Venue
{
get
{
return _venue;
}
set
{
if (_venue != value)
{
_venue = value;
OnNotifyPropertyChanged("Venue");
}
}
}
public ObservableCollection<VenueData> Venues
{
get
{
return _venues;
}
set
{
if (_venues != value)
{
_venues = value;
OnNotifyPropertyChanged("Venues");
}
}
}
public void GetAllVenues()
{
TicketOrderWcfClient toClient = new TicketOrderWcfClient();
toClient.GetVenuesCompleted += new EventHandler<GetVenuesCompletedEventArgs>(toClient_GetVenuesCompleted);
toClient.GetVenuesAsync();
}
void toClient_GetVenuesCompleted(object sender, GetVenuesCompletedEventArgs e)
{
if (e.Error == null)
Venues = e.Result;
}
}
MainPage.xaml(视图 )
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
VenueViewModel vvm = new VenueViewModel();
vvm.GetAllVenues();
MessageBox.Show(vvm.Venues.Count.ToString());
}
这是大部分代码。问题是,在MainPage_Loaded事件vvm. getall场馆()将不会填充场馆ObservableCollection。MessageBox将显示0。我测试了wcf的服务是好的,也小提琴显示肥皂细。此外,如果我在MainPage_Loaded事件中调用wcf服务,那么它将工作。见下文:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
TicketOrderWcfClient toClient = new TicketOrderWcfClient();
toClient.GetVenuesCompleted += new EventHandler<GetVenuesCompletedEventArgs>(toClient_GetVenuesCompleted);
toClient.GetVenuesAsync();
}
void toClient_GetVenuesCompleted(object sender, GetVenuesCompletedEventArgs e)
{
if(e.Error == null)
{
VenueViewModel vvm = new VenueViewModel();
vvm.Venues = e.Result;
MessageBox.Show(vvm.Venues.Count.ToString());
}
}
这次MessageBox将显示3,这很好,因为db中有3条记录。所以看起来视图和ViewModel之间有问题。我怀疑我在这里错过了一个非常基本的东西。还要注意,我知道这不是真正的MVVM,但我必须以这种方式完成这个程序。我希望我的解释清楚,谢谢你的帮助。
在您的第一种方法中,它不起作用,代码流:
MessageBox.Show(vvm.Venues.Count.ToString());
与WCF方法异步调用的终止没有连接!换句话说,您显示了mbox,但您不确保异步调用已经终止。
当然,您已经为GetVenuesCompleted事件分配了一个委托,但是toClient.GetVenuesAsync()的调用是一个异步调用,这意味着在调用时它不会等待结果(终止)。所以当你调用:
vvm.GetAllVenues();
然后MessageBox.Show(vvm.Venues.Count.ToString());
比你的toClient_GetVenuesCompleted委托调用得更快。
你的第二种方法是有效的,因为你在异步方法完成时显示消息框(在你的getlocations回调中)。
在我看来,你可以修复它,例如通过在VenueViewModel中添加一个新的事件GetAllVenuesCompleted,它将在toClient_GetVenuesCompleted委托的末尾被触发。换句话说,我会进一步传递这个事件。另外,我要添加一个注释,getall场馆是一个异步方法。
我猜问题是,您正在创建新的VM。
void toClient_GetVenuesCompleted(object sender, GetVenuesCompletedEventArgs e)
{
if(e.Error == null)
{
VenueViewModel vvm = new VenueViewModel();
vvm.Venues = e.Result;
MessageBox.Show(vvm.Venues.Count.ToString());
}
}
我认为这段代码可以工作。你创建新的VenueViewModel,用数据填充它,这就是全部。该虚拟机不会再被使用。对于MainPage也是同样的规则。xaml样本。
你应该在构造函数/加载处理程序中创建VenuViewModel的全局变量,并在加载事件