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,但我必须以这种方式完成这个程序。我希望我的解释清楚,谢谢你的帮助。

Silverlight 4 + WCF与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的全局变量,并在加载事件

中调用它的getalllocations