通过异步方法将可观察的集合填充到列表视图中

时间:2018-08-29 15:34:42

标签: c# .net uwp async-await observablecollection

我有一个列表,并使用for循环的方法填充列表。只是一个从1到10的数字。然后,我创建了一个列表视图,并通过将我从方法获得的列表转换为可观察的集合,以Observable集合填充了它。在执行该程序时,我可以看到列表视图中填充了数字。 但是当我用异步方法填充相同的列表时,我看不到列表视图被填充。我使用断点来检查方法是否有效。但是这些方法都可以正常工作。甚至我的可观察集合也被填充。但我看不到列表视图。

这是我的程序:

<Page
    x:Class="UWPListView.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UWPListView"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility  /2006"
    xmlns:data="using:UWPListView.Models"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel>
            <ProgressRing IsActive="True" Width="50" Height="50"
                          Foreground="Red" Name="MyProgress"/>
            <TextBlock Text="ListItems" FontSize="30"/>
        </StackPanel>

        <ListView Grid.Row="1" ItemsSource="{x:Bind ListItems}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="data:ListItem">
                <TextBlock Text="{x:Bind Number}" VerticalAlignment="Center"Margin="10,0,0,0" Foreground="Red"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid> 
</Page>

Mainpage.xaml.cs

namespace UWPListView
{
    public sealed partial class MainPage : Page
    {
        private ObservableCollection<ListItem> ListItems;

        public MainPage()
        {
            this.InitializeComponent();
            ThisMethod().GetAwaiter();
        }

        private async Task ThisMethod()
        {
            MyProgress.Visibility = Visibility.Visible;
            ObservableCollection<ListItem> items = new ObservableCollection<ListItem>(await ListManager.GetItemsAsync());
            ListItems = items;
            MyProgress.Visibility = Visibility.Collapsed;
        }
    }
}

我的课

namespace UWPListView.Models
{
    public class ListItem
    {
        public float Number { get; set; }
    }

    public class ListManager
    {
        public async static Task<List<ListItem>> GetItemsAsync()
        {
            var listItems = new List<ListItem>();
            Rootobject temperatures = await getTemperatureAsync();

            for (int i = 0; i < 3; i++)
            {
                listItems.Add(new ListItem() { Number = temperatures.hourly.data[i].temperature });
            }
            return listItems;
        }

        private async static Task<Rootobject> getTemperatureAsync()
        {
            HttpClient client = new HttpClient();
            var jsonData = await client.GetStringAsync("https://api.darksky.net/forecast/apikey/13.08,80.27?units=si");
            var parsedData = JsonConvert.DeserializeObject<Rootobject>(jsonData);
            return parsedData;
        }
    }

我已经在Models文件夹下创建了该类,并且还包含了以下语句      xmlns:data =“ using:UWPListView.Models” 和     使用UWPListView.Models;

3 个答案:

答案 0 :(得分:1)

我建议在加载页面时创建一个事件处理程序

类似的东西:

<Page
...
Loaded="MainPage_OnLoaded">

然后在您的代码隐藏中即可:

private async void MainPage_OnLoaded(object sender, RoutedEventArgs e)
{
    await ThisMethod();
}

您可能还想离开构造函数而只初始化成员。

答案 1 :(得分:0)

使用我在下面为您的课程提供的代码,我为您简化了事情。

  

您不需要在构造函数中执行 GetAwaiter()

     

此外,您还需要在构造函数中初始化observableCollection

public sealed partial class MainPage : Page
{
    private ObservableCollection<ListItem> ListItems;

    public MainPage()
    {
        this.InitializeComponent();
        this.Loaded += MainPageLoaded; //if you dont want to use loaded method u can use OnnavigatedTo() override as well.
        ObservableCollection<ListItem> ListItems = new ObservableCollection<ListItem>();
    }

    private async void MainPageLoaded(object sender, RoutedEventArgs e)
    {
        await ThisMethod();
    }

    private async Task ThisMethod()
    {
        MyProgress.Visibility = Visibility.Visible;
        var items = await ListManager.GetItemsAsync();
        foreach(var item in items)
        {
            ListItems.Add(item);
        }
        MyProgress.Visibility = Visibility.Collapsed;
    }
}

答案 2 :(得分:0)

请勿使用enter image description here

  

此方法仅供编译器使用,而不是在应用程序代码中使用。

我会修改您的应用,以便等到页面加载完毕,然后加载模型:

namespace UWPListView
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<ListItem> Model; // change your XAML to bind to Model instead of ListItems

        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += new RoutedEventHandler(OnLoaded);
        }

        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            MyProgress.Visibility = Visibility.Visible;
            this.Model = await ListManager.GetItemsAsync();
            MyProgress.Visibility = Visibility.Collapsed;
        } 
    }
}

请注意,事件处理程序是应使用async void而非async TaskTask.GetAwaiter())的仅有的地方之一。