简体   繁体   English

如何异步加载元素

[英]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 在这里,我将listview收费到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. 这并不意味着您向方法添加async关键字,然后它将成为异步方法。 Please see Asynchronous Programming with async and await in c# to learn asynchronous programming and see Asynchronous Programming in UWP for more details. 请参阅使用async进行异步编程并在c#中等待学习异步编程,并在UWP中查看异步编程以获取更多详细信息。

The second, you use the StackPanel as the ListView's ItemsPanelTemplate. 第二,使用StackPanel作为ListView的ItemsPanelTemplate。 This involves UI virtualization-related content. 这涉及与UI虚拟化相关的内容。 In a word, using the StackPanel will decrease the ListView performance. 总之,使用StackPanel会降低ListView的性能。 You could use ItemsStackPanel . 您可以使用ItemsStackPanel Please see ListView and GridView UI optimization for more information. 有关更多信息,请参阅ListView和GridView UI优化

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. 相反,您可以在页面的Loaded事件处理程序中调用它。

For you above code snippet, I did some changes in it and keep it from blocking the UI thread. 对于你上面的代码片段,我做了一些更改,并防止它阻止UI线程。 In order to see more clearly, I added this line code await Task.Delay(1000); 为了更清楚地看到,我添加了这个行代码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. 然后您将清楚地看到ListView逐行添加到UI上,但页面仍然是响应式的。

<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);
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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