loop
loop

Reputation: 9242

observable collection in async method

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

Answers (1)

Rafal
Rafal

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 ItemsControls 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

Related Questions