Windows Phone Silverlight中的UI未更新
我正在尝试创建一个Windows Phone应用程序。我一直在观察,但是我遇到了一些问题,视图没有用数据更新(模板只是空的) 我已经确定items集合实际上是用数据设置的,但我怀疑是NotifyPropertyChanged事件没有正确触发 我可能会错过什么 我的MainViewModel如下所示: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
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都有效。谢谢!很乐意帮忙。数据绑定一开始可能很棘手,但它很快就会成为你最好的朋友。