Windows Phone Silverlight中的UI未更新

Windows Phone Silverlight中的UI未更新,silverlight,windows-phone-7,Silverlight,Windows Phone 7,我正在尝试创建一个Windows Phone应用程序。我一直在观察,但是我遇到了一些问题,视图没有用数据更新(模板只是空的) 我已经确定items集合实际上是用数据设置的,但我怀疑是NotifyPropertyChanged事件没有正确触发 我可能会错过什么 我的MainViewModel如下所示: public class MainViewModel : INotifyPropertyChanged { private ServiceAgent _serviceAgent; p

我正在尝试创建一个Windows Phone应用程序。我一直在观察,但是我遇到了一些问题,视图没有用数据更新(模板只是空的)

我已经确定items集合实际上是用数据设置的,但我怀疑是NotifyPropertyChanged事件没有正确触发

我可能会错过什么

我的MainViewModel如下所示:

public class MainViewModel : INotifyPropertyChanged
{
    private ServiceAgent _serviceAgent;
    public MainViewModel()
    {
        this.Items = new ObservableCollection<SocialListItemViewModel>();
        if (_serviceAgent == null)
        {
            _serviceAgent = new ServiceAgent();
        }
    }

    /// <summary>
    /// A collection for ItemViewModel objects.
    /// </summary>
    public ObservableCollection<SocialListItemViewModel> Items { get; private set; }

    public bool IsDataLoaded
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public void LoadData()
    {
        _serviceAgent.GetSocialItems();
        _serviceAgent.SocialItemsLoaded += new ServiceAgent.SocialListItemsLoadedEventHandler(_serviceAgent_SocialItemsLoaded);

        //// Sample data; replace with real data
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });

        this.IsDataLoaded = true;
    }

    void _serviceAgent_SocialItemsLoaded(ObservableCollection<SocialListItemViewModel> socialItems)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                      {

                                                          this.Items = socialItems;

                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          NotifyPropertyChanged("ContentShort");
                                                      });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
[DataContract]
public class SocialListItemViewModel : INotifyPropertyChanged
{

    private string _contentshort;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ContentShort
    {
        get
        {
            return _contentshort;
        }
        set
        {
            if (value != _contentshort)
            {
                _contentshort = value;
                NotifyPropertyChanged("ContentShort");
            }
        }
    }

    private string _imageUrl;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ImageUrl
    {
        get
        {
            return _imageUrl;
        }
        set
        {
            if (value != _imageUrl)
            {
                _imageUrl = value;
                NotifyPropertyChanged("ImageUrl");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class ServiceAgent
{
    public delegate void SocialListItemsLoadedEventHandler(ObservableCollection<SocialListItemViewModel> socialItems);
    public event SocialListItemsLoadedEventHandler SocialItemsLoaded;

    private ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();
    public void GetSocialItems()
    {
        WebClient wcNewsTractor = new WebClient();
        wcNewsTractor.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wcNewsTractor_DownloadStringCompleted);
        wcNewsTractor.DownloadStringAsync(new Uri("URL TO JSON FEED"));

    }

    void wcNewsTractor_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null && e.Cancelled == false)
        {
            //ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();

            ThreadPool.QueueUserWorkItem((s) =>
            {
            socialListItemViewModels = ReadToObject(e.Result);
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                          {
                                                              SocialItemsLoaded(socialListItemViewModels);
                                                          });

            });

        }
    }

    // Deserialize a JSON stream to a User object.
    public static ObservableCollection<SocialListItemViewModel> ReadToObject(string json)
    {
        ObservableCollection<SocialListItemViewModel> res = new ObservableCollection<SocialListItemViewModel>();
        List<SocialListItemViewModel> deserializedItems = new List<SocialListItemViewModel>();
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
        DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedItems.GetType());
        deserializedItems = ser.ReadObject(ms) as List<SocialListItemViewModel>;
        ms.Close();
        return new ObservableCollection<SocialListItemViewModel>(deserializedItems);
    }
}
public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context of the listbox control to the sample data
            DataContext = new SocialListItemViewModel(); //App.ViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                  <StackPanel Margin="0,0,0,17" Width="432" Height="225" d:DataContext="{d:DesignData /SampleData/SocialListItemViewModelSampleData1.xaml}">
                      <Image  Height="125" Width="125" Margin="0" Source="http://myimage.com/myimage.jpg" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                      <TextBlock x:Name="ContentShort" Text="{Binding ContentShort}" TextWrapping="Wrap" Margin="0,-125,0,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Right" Foreground="#99FFFFFF" Width="279" RenderTransformOrigin="0.459,0.513" VerticalAlignment="Center" Height="160"/>
                      <Button Name="btnVote" Height="72" HorizontalAlignment="Center" Width="225" Margin="0,-10,-130,0" VerticalAlignment="Center" BorderThickness="2" Content="Vote" Background="#FF0090A1" />
                  </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
 Deployment.Current.Dispatcher.BeginInvoke(() =>
                       {
                           this.Items.Clear();
                           foreach(var item in socialItems)
                           {
                                this.Items.Add(item);
                           }
                       }
添加模板的MainPage.xaml如下所示:

public class MainViewModel : INotifyPropertyChanged
{
    private ServiceAgent _serviceAgent;
    public MainViewModel()
    {
        this.Items = new ObservableCollection<SocialListItemViewModel>();
        if (_serviceAgent == null)
        {
            _serviceAgent = new ServiceAgent();
        }
    }

    /// <summary>
    /// A collection for ItemViewModel objects.
    /// </summary>
    public ObservableCollection<SocialListItemViewModel> Items { get; private set; }

    public bool IsDataLoaded
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public void LoadData()
    {
        _serviceAgent.GetSocialItems();
        _serviceAgent.SocialItemsLoaded += new ServiceAgent.SocialListItemsLoadedEventHandler(_serviceAgent_SocialItemsLoaded);

        //// Sample data; replace with real data
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });

        this.IsDataLoaded = true;
    }

    void _serviceAgent_SocialItemsLoaded(ObservableCollection<SocialListItemViewModel> socialItems)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                      {

                                                          this.Items = socialItems;

                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          NotifyPropertyChanged("ContentShort");
                                                      });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
[DataContract]
public class SocialListItemViewModel : INotifyPropertyChanged
{

    private string _contentshort;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ContentShort
    {
        get
        {
            return _contentshort;
        }
        set
        {
            if (value != _contentshort)
            {
                _contentshort = value;
                NotifyPropertyChanged("ContentShort");
            }
        }
    }

    private string _imageUrl;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ImageUrl
    {
        get
        {
            return _imageUrl;
        }
        set
        {
            if (value != _imageUrl)
            {
                _imageUrl = value;
                NotifyPropertyChanged("ImageUrl");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class ServiceAgent
{
    public delegate void SocialListItemsLoadedEventHandler(ObservableCollection<SocialListItemViewModel> socialItems);
    public event SocialListItemsLoadedEventHandler SocialItemsLoaded;

    private ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();
    public void GetSocialItems()
    {
        WebClient wcNewsTractor = new WebClient();
        wcNewsTractor.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wcNewsTractor_DownloadStringCompleted);
        wcNewsTractor.DownloadStringAsync(new Uri("URL TO JSON FEED"));

    }

    void wcNewsTractor_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null && e.Cancelled == false)
        {
            //ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();

            ThreadPool.QueueUserWorkItem((s) =>
            {
            socialListItemViewModels = ReadToObject(e.Result);
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                          {
                                                              SocialItemsLoaded(socialListItemViewModels);
                                                          });

            });

        }
    }

    // Deserialize a JSON stream to a User object.
    public static ObservableCollection<SocialListItemViewModel> ReadToObject(string json)
    {
        ObservableCollection<SocialListItemViewModel> res = new ObservableCollection<SocialListItemViewModel>();
        List<SocialListItemViewModel> deserializedItems = new List<SocialListItemViewModel>();
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
        DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedItems.GetType());
        deserializedItems = ser.ReadObject(ms) as List<SocialListItemViewModel>;
        ms.Close();
        return new ObservableCollection<SocialListItemViewModel>(deserializedItems);
    }
}
public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context of the listbox control to the sample data
            DataContext = new SocialListItemViewModel(); //App.ViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                  <StackPanel Margin="0,0,0,17" Width="432" Height="225" d:DataContext="{d:DesignData /SampleData/SocialListItemViewModelSampleData1.xaml}">
                      <Image  Height="125" Width="125" Margin="0" Source="http://myimage.com/myimage.jpg" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                      <TextBlock x:Name="ContentShort" Text="{Binding ContentShort}" TextWrapping="Wrap" Margin="0,-125,0,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Right" Foreground="#99FFFFFF" Width="279" RenderTransformOrigin="0.459,0.513" VerticalAlignment="Center" Height="160"/>
                      <Button Name="btnVote" Height="72" HorizontalAlignment="Center" Width="225" Margin="0,-10,-130,0" VerticalAlignment="Center" BorderThickness="2" Content="Vote" Background="#FF0090A1" />
                  </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
 Deployment.Current.Dispatcher.BeginInvoke(() =>
                       {
                           this.Items.Clear();
                           foreach(var item in socialItems)
                           {
                                this.Items.Add(item);
                           }
                       }

好的,我认为这里可能发生的事情是,您没有为ObservableCollection
项触发notify

在这方面:

 Deployment.Current.Dispatcher.BeginInvoke(() =>
                       {
                           this.Items = socialItems;
您正在丢弃旧的ObservableCollection,并将其分配给从您的服务返回的集合。ObservableCollection只在添加/删除时发送通知,因此当您这样做时,不会向视图触发任何内容

有两种方法可以解决这个问题。一种是使用私有支持成员变量设置
Items
,并在setter中调用
NotifyPropertyChanged(“Items”)
。或者,您可以返回一个通用的
列表
,并遍历内容,将其添加到
集合中,类似于以下内容:

public class MainViewModel : INotifyPropertyChanged
{
    private ServiceAgent _serviceAgent;
    public MainViewModel()
    {
        this.Items = new ObservableCollection<SocialListItemViewModel>();
        if (_serviceAgent == null)
        {
            _serviceAgent = new ServiceAgent();
        }
    }

    /// <summary>
    /// A collection for ItemViewModel objects.
    /// </summary>
    public ObservableCollection<SocialListItemViewModel> Items { get; private set; }

    public bool IsDataLoaded
    {
        get;
        private set;
    }

    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public void LoadData()
    {
        _serviceAgent.GetSocialItems();
        _serviceAgent.SocialItemsLoaded += new ServiceAgent.SocialListItemsLoadedEventHandler(_serviceAgent_SocialItemsLoaded);

        //// Sample data; replace with real data
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
        //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });

        this.IsDataLoaded = true;
    }

    void _serviceAgent_SocialItemsLoaded(ObservableCollection<SocialListItemViewModel> socialItems)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                      {

                                                          this.Items = socialItems;

                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu suscipit torquent", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Ultrices vehicula volutpat maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          //this.Items.Add(new SocialListItemViewModel() { ContentShort = "Maecenas praesent accumsan bibendum dictumst eleifend facilisi faucibus habitant inceptos interdum lobortis nascetur", ImageUrl = "http://profile.ak.fbcdn.net/hprofile-ak-ash2/50215_277666338969761_534345200_t.jpg" });
                                                          NotifyPropertyChanged("ContentShort");
                                                      });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
[DataContract]
public class SocialListItemViewModel : INotifyPropertyChanged
{

    private string _contentshort;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ContentShort
    {
        get
        {
            return _contentshort;
        }
        set
        {
            if (value != _contentshort)
            {
                _contentshort = value;
                NotifyPropertyChanged("ContentShort");
            }
        }
    }

    private string _imageUrl;
    /// <summary>
    /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
    /// </summary>
    /// <returns></returns>
    [DataMember]
    public string ImageUrl
    {
        get
        {
            return _imageUrl;
        }
        set
        {
            if (value != _imageUrl)
            {
                _imageUrl = value;
                NotifyPropertyChanged("ImageUrl");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class ServiceAgent
{
    public delegate void SocialListItemsLoadedEventHandler(ObservableCollection<SocialListItemViewModel> socialItems);
    public event SocialListItemsLoadedEventHandler SocialItemsLoaded;

    private ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();
    public void GetSocialItems()
    {
        WebClient wcNewsTractor = new WebClient();
        wcNewsTractor.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wcNewsTractor_DownloadStringCompleted);
        wcNewsTractor.DownloadStringAsync(new Uri("URL TO JSON FEED"));

    }

    void wcNewsTractor_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null && e.Cancelled == false)
        {
            //ObservableCollection<SocialListItemViewModel> socialListItemViewModels = new ObservableCollection<SocialListItemViewModel>();

            ThreadPool.QueueUserWorkItem((s) =>
            {
            socialListItemViewModels = ReadToObject(e.Result);
            Deployment.Current.Dispatcher.BeginInvoke(() =>
                                                          {
                                                              SocialItemsLoaded(socialListItemViewModels);
                                                          });

            });

        }
    }

    // Deserialize a JSON stream to a User object.
    public static ObservableCollection<SocialListItemViewModel> ReadToObject(string json)
    {
        ObservableCollection<SocialListItemViewModel> res = new ObservableCollection<SocialListItemViewModel>();
        List<SocialListItemViewModel> deserializedItems = new List<SocialListItemViewModel>();
        MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
        DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedItems.GetType());
        deserializedItems = ser.ReadObject(ms) as List<SocialListItemViewModel>;
        ms.Close();
        return new ObservableCollection<SocialListItemViewModel>(deserializedItems);
    }
}
public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context of the listbox control to the sample data
            DataContext = new SocialListItemViewModel(); //App.ViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged" ItemContainerStyle="{StaticResource ListBoxItemStyle1}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                  <StackPanel Margin="0,0,0,17" Width="432" Height="225" d:DataContext="{d:DesignData /SampleData/SocialListItemViewModelSampleData1.xaml}">
                      <Image  Height="125" Width="125" Margin="0" Source="http://myimage.com/myimage.jpg" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                      <TextBlock x:Name="ContentShort" Text="{Binding ContentShort}" TextWrapping="Wrap" Margin="0,-125,0,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Right" Foreground="#99FFFFFF" Width="279" RenderTransformOrigin="0.459,0.513" VerticalAlignment="Center" Height="160"/>
                      <Button Name="btnVote" Height="72" HorizontalAlignment="Center" Width="225" Margin="0,-10,-130,0" VerticalAlignment="Center" BorderThickness="2" Content="Vote" Background="#FF0090A1" />
                  </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
 Deployment.Current.Dispatcher.BeginInvoke(() =>
                       {
                           this.Items.Clear();
                           foreach(var item in socialItems)
                           {
                                this.Items.Add(item);
                           }
                       }

如何将viewmodel分配给视图(例如,在何处设置DataContext)?——另外,请出示相关的xaml。嗨,Robaticus,我使用标准的“Windows Phone数据绑定应用程序”作为模板。我已经将主页中的上下文更改为SocialListItem,这是我的视图模型。这很有意义。装订在单子上。清除列表和手动调用NotifyPropertyChanged都有效。谢谢!很乐意帮忙。数据绑定一开始可能很棘手,但它很快就会成为你最好的朋友。