简体   繁体   中英

How to load element asynchronously

I want each template to be loaded into my stackpanel individually and not have to wait until they are all ready, is there any way to make it load one by one without the program freezing, while others still load?

Here I charge the listview to the stackpanel

    public MainPage()
    {
        this.InitializeComponent();
        setdata();
    }

    public async void setdata()
    {

        for (int i = 0; i < 30; i++)
        {
            DataTemplate template = this.Resources["listT"] as DataTemplate;
            var element = template.LoadContent() as UIElement;
            ListView list = element as ListView;

            for (int j = 0; j < 20; j++)
            {
                listS.Add("t: " + j);
            }
            list.DataContext = listS;
            root.Children.Add(list);
        }

    }

and

  <Page.Resources>
        <ResourceDictionary>
            <ItemsPanelTemplate x:Key="HorizontalTemplate">
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
            <DataTemplate x:Key="HorizontalBoxeSectionTemplate">
                <Grid Background="White">
                    <Image Source="/Assets/image.jpg"  Stretch="UniformToFill"/>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="listT">
                <ListView  Grid.Row="1"
                               IsItemClickEnabled="True"
                               ScrollViewer.HorizontalScrollMode="Enabled" 
                               ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
                               ScrollViewer.IsHorizontalRailEnabled="True"     
                               ItemsPanel="{StaticResource HorizontalTemplate}"
                               ItemsSource="{Binding }"
                               ItemTemplate="{StaticResource HorizontalBoxeSectionTemplate}">
                    <ListView.ItemContainerStyle>
                        <Style TargetType="ListViewItem">
                            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        </Style>
                    </ListView.ItemContainerStyle>
                </ListView>
            </DataTemplate>
        </ResourceDictionary>
    </Page.Resources>

    <StackPanel Name="root">

    </StackPanel>

There're three issues in your code.

The first, you need to understand the asynchronous programming. It doesn't mean that you add a async keyword to the method and then it will become an asynchronous method. Please see Asynchronous Programming with async and await in c# to learn asynchronous programming and see Asynchronous Programming in UWP for more details.

The second, you use the StackPanel as the ListView's ItemsPanelTemplate. This involves UI virtualization-related content. In a word, using the StackPanel will decrease the ListView performance. You could use ItemsStackPanel . Please see ListView and GridView UI optimization for more information.

The third, you'd better not call an asynchronous method in the page's constructor. Instead, you could call it in the page's Loaded event handler.

For you above code snippet, I did some changes in it and keep it from blocking the UI thread. In order to see more clearly, I added this line code await Task.Delay(1000); . Then you will clearly see that ListView is added on the UI line by line, but the page is still responsive.

<ItemsPanelTemplate x:Key="HorizontalTemplate">
    <ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        this.Loaded += MainPage_Loaded;
    }

    private async void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        await setdata();
    }

    public List<string> listS { get; set; } = new List<string>();

    public async Task setdata()
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            for (int i = 0; i < 30; i++)
            {
                DataTemplate template = this.Resources["listT"] as DataTemplate;
                var element = template.LoadContent() as UIElement;
                ListView list = element as ListView;

                for (int j = 0; j < 20; j++)
                {
                    listS.Add("t: " + j);
                }
                list.DataContext = listS;
                root.Children.Add(list);
                await Task.Delay(1000);
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM