Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Updating list view with repeated API calls

Posted on 2016-08-05
4
Medium Priority
?
76 Views
Last Modified: 2016-08-09
Hi Experts,

I am developing a Universal Windows Platform software with VS2015 CE. I am calling some web API through JSON and passing those data to my application.

I have one list view that displays a list of data call from various APIs. The whole list view needs to be replaced with a button click event. The list is being generated the first time when the application is loading. However the list does not seem to be refreshed with the desired button click.

Part of my Code is as follows:
-------------------------------------------

private void btnCur_Click(object sender, RoutedEventArgs e)
        {
            if (btnCur.Content.Equals("USD"))
                btnCur.Content="EUR";

            else
                btnCur.Content = "USD";

            gdContents(Convert.ToString(btnCur.Content));
        }

private async void gdContents(string un)
        {
            MyProgressRing.IsActive = true;
            MyProgressRing.Visibility = Visibility.Visible;

            //The APIData class has a function to manage the API calls and put them in a list
            Data = new ObservableCollection<APIData>();     
            await APIDataManager.PopulateAPIDataAsync(Data, un);

            MyProgressRing.IsActive = false;
            MyProgressRing.Visibility = Visibility.Collapsed;
        }

Open in new window


Regards,
Soumen
0
Comment
Question by:Soumen Roy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 10

Expert Comment

by:Paweł
ID: 41747368
your issue is most likely a threading one, by making your gdContents async but returning void your application isn't syncing with the UI thread (that maybe a bad explanation)

to fix it, set your button click as async
make your gdContents methode return a Task then at the end of your method return a null object.

 return Task.FromResult<object>(null);

private async void btnCur_Click(object sender, RoutedEventArgs e)
        {
            if (btnCur.Content.Equals("USD"))
                btnCur.Content="EUR";

            else
                btnCur.Content = "USD";

          await gdContentsAsync(Convert.ToString(btnCur.Content));
        }

private async Task<object> gdContentsAsync(string un)
        {
            MyProgressRing.IsActive = true;
            MyProgressRing.Visibility = Visibility.Visible;

            //The APIData class has a function to manage the API calls and put them in a list
            Data = new ObservableCollection<APIData>();     
            await APIDataManager.PopulateAPIDataAsync(Data, un);

            MyProgressRing.IsActive = false;
            MyProgressRing.Visibility = Visibility.Collapsed;

            return await Task.FromResult<object>(null);
        }

Open in new window


try that and let me know if it works

Ok try that
0
 
LVL 10

Expert Comment

by:Paweł
ID: 41747431
If that doesn't work, could you post your APIDataManager.PopulateAPIDataAsync method
0
 
LVL 10

Accepted Solution

by:
Paweł earned 2000 total points
ID: 41747486
actually you're problem is in re-instantiating of your observable collection

Data = new ObservableCollection<APIData>();

by doing that your're essentially breaking your binding, try clearing it

if you do data.clear()

and then you get a thread marshaled error, then you have the problem that i mentioned before with an inability to communicate with your UI thread, you can hack it by using the

  await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
            () => { //  });


so if your xaml is

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView ItemsSource="{Binding MyThings, Mode=TwoWay}"/>
        <Button Content="ToFrench" Click="Button_Click"/>
    </Grid>
</Page>

Open in new window


and you're code-behind is

using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App1
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<string> MyThings { get; set; }
        public MainPage()
        {
            MyThings = new ObservableCollection<string>();
            MyThings.Add("One");
            MyThings.Add("Two");
            MyThings.Add("Three");
            this.InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            await ToFrench();

        }

        async Task<object> ToFrench()
        {
            MyThings.Clear();
            await PopulateFrenchDataAsync(MyThings);
            return await Task.FromResult<object>(null);
        }

        async Task<object> PopulateFrenchDataAsync(ObservableCollection<string> Data)
        {
            await Task.Run(() =>
              
                {
                    Data.Add("un");
                    Data.Add("deux");
                    Data.Add("trois");

                });

            return await Task.FromResult<object>(null);
        }
    }
}

Open in new window


change your update logic to

  async Task<object> PopulateFrenchDataAsync(ObservableCollection<string> Data)
        {
            await Task.Run(async () =>
                await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    Data.Add("un");
                    Data.Add("deux");
                    Data.Add("trois");

                }));

            return await Task.FromResult<object>(null);
        }

Open in new window

0
 

Author Closing Comment

by:Soumen Roy
ID: 41748661
Thanks for your help. It worked nicely :-)
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
The purpose of this video is to demonstrate how to Import and export files in WordPress. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp-login.php : Click on Too…
The purpose of this video is to demonstrate how to set up the permalinks on a WordPress Website. This will be demonstrated using a Windows 8 PC. Go to your WordPress login page. This will look like the following: mywebsite.com/wp-login.php : Go t…
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question