在 ItemsControl WPF C# 中异步加载用户控件

Async Loading UserControls in ItemControl WPF C#

我想从 tmdb 打印电影信息 api 并将电影信息打印到用户控件中。我想让程序显示一张海报,它的名字,它的发布日期,有多少票等等。我的问题就从这里开始,我想异步加载 usercontrolls,所以我希望同时将它们全部加载到我的 main window 中。但是我做不到,他们正在一个接一个地加载。有没有办法在 UI 更新中使用 Async?还是有另一种方法来实现这一目标?我想与网页同时获取所有 20 个电影海报的名称,并将这 20 个用户控件同时添加到我的主 window。我现在正在使用这段代码:

private async  void Page_Loaded(object sender, RoutedEventArgs e)
        {
          await  GetPopularMoviesAsync();


        }

        public async Task GetPopularMoviesAsync()
        {
             SearchContainer<SearchMovie> popularMovies = await client.GetMoviePopularListAsync("en", 1);
              List<SearchMovie> popularMovieList = popularMovies.Results;
              foreach (var searchMovie in popularMovieList)
              {
                  MovieUSC mov = new MovieUSC();
                  var image = await GetMovieImage(searchMovie);
                  GetPosterFromFile(image, mov.MoviePoster);

                  mov.Name = "PopularMovies" + searchMovie.Id;
                  mov.MovieName.Text = searchMovie.OriginalTitle;

                  mov.MovieReleaseDate.Text = "(" + searchMovie.ReleaseDate.Value.Year + ")";
                  mov.MovieRatingBar.Value = Convert.ToInt32(searchMovie.VoteAverage) / 2;
                  mov.ClickedMovie += ClickedMovie;
                  MoviePanel.Items.Add(mov);

              }
        }

即使您不想走整个 MVVM 路线,将数据访问与 UI 分开仍然是一个好习惯。

使用 ObservableCollection<> 保存搜索结果,这将成为显示的驱动程序 - 每次刷新时都会自动更新任何绑定的控件。

public ObservableCollection<SearchMovie> PopularMovies { get; } 
    = new public ObservableCollection<SearchMovie>(); 

private async void Page_Loaded(object sender, RoutedEventArgs e)
{
    var popularMovies = await client.GetMoviePopularListAsync("en", 1);

    PopularMovies.Clear();
    foreach(var movie in popularMovies)
        PopularMovies.Add(movie); 
}

如果您希望用户能够 select 特定电影项目,您的 window 应该使用 ListBox,否则 ItemsControl。在任一情况下,将 ItemsSource 设置为 PopularMovies 集合。使用 DataTemplate 定义每个电影项目的布局 - 每个控件都绑定到 SearchMovie 对象的适当 属性。

<ItemsContol x:Name="MoviesDisplay">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
             <StackPanel>
                  <TextBlock Text="{Binding OriginalTitle}" />
                  <TextBlock Text="{Binding ReleaseDate.Value.Year}" />

                  // Add more controls here as required
             </StackPanel>
        </DataTemplate> 
    </ItemsControl.ItemTemplate>
</ItemsControl>