Reputation: 9242
Hello friends i am getting very strange problem by using ObservableCollection in an async method in my windows store app. I am trying to add items in an ObservableCollection in an async method it is working fine if i define the ObservableCollection above a line where await keyword is but i initialize below this line it is not working. i have made sample for this problem. my xaml code is..
<Page
x:Class="observableCollectionTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:observableCollectionTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding SomeCollection}" Background="Pink" HorizontalAlignment="Left" Width="500" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="200" Height="200" Background="Red" >
<Button Content="click me" Name="btn" ></Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
my mainpage backhand working code is..
public sealed partial class MainPage : Page
{
public ObservableCollection<string> SomeCollection { get; set; }
public MainPage()
{
this.InitializeComponent();
FillCollection();
this.DataContext = this;
}
public async Task FillCollection()
{
SomeCollection = new ObservableCollection<string>(); // it is working..
HttpClient client = new HttpClient();
HttpResponseMessage message = await client.GetAsync("https://www.google.co.in/");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
}
my mainpage backhand FillCollection code that is not working..
public async Task FillCollection()
{
HttpClient client = new HttpClient();
HttpResponseMessage message = await client.GetAsync("https://www.google.co.in/");
SomeCollection = new ObservableCollection<string>(); // this is not working
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
SomeCollection.Add("asd");
}
i am not getting why is this happening. i am missing some concept here please tell me..any kind of help or suggestion is appreciated..
Upvotes: 2
Views: 2523
Reputation: 12619
You are lacking property change event firing from your SomeCollection
property - see this on how to implement that.
The reason it is needed is that the part of your FillCollection
method before async is executed before you assign DataContext
property and the other half after web request is finished. So in your not working example the View
does not know that whole collection was changed.
On the other hand consider what you are loosing assigning new instance of ObservableCollection
on every list refresh (you want to refresh it at some point?). The underlying of this class is to provide UI way to optimize refreshing of items in ItemsControl
s by knowing which elements where added/removed/moved if you crate a new collection whole ListView
will be rerendered which can be expensive. I suggest to move your assignment to constructor before FillCollection
call for code clarity reasons and handle content change nicely - it is more work for you but if view is complicated it is worth it.
Upvotes: 2