如何异步加载元素

时间:2019-04-29 23:35:38

标签: c# uwp

我希望每个模板都单独加载到我的堆栈面板中,而不必等到它们全部准备好后,有什么方法可以使其一个一个地加载而不会使程序冻结,而其他模板仍可以加载吗?

在这里,我将listview充入堆栈面板

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

    }

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

1 个答案:

答案 0 :(得分:0)

您的代码中存在三个问题。

首先,您需要了解异步编程。这并不意味着您向该方法添加一个async关键字,然后它将变成一个异步方法。请参阅Asynchronous Programming with async and await in c#以学习异步编程,请参阅Asynchronous Programming in UWP了解更多详细信息。

第二,将StackPanel用作ListView的ItemsPanelTemplate。这涉及与UI虚拟化相关的内容。总之,使用StackPanel将降低ListView性能。您可以使用ItemsStackPanel。有关更多信息,请参见ListView and GridView UI optimization

第三,最好不要在页面的构造函数中调用异步方法。相反,您可以在页面的Loaded事件处理程序中调用它。

对于上面的代码片段,我做了一些更改,以防止其阻塞UI线程。为了更清楚地看到,我添加了此行代码await Task.Delay(1000);。然后,您将清楚地看到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);
            }
        });
    }
}