简体   繁体   中英

Async Loading UserControls in ItemControl WPF C#

I would like to print the movie information from the tmdb api and print the movie information into the usercontrols. I want the program to show a poster, its name, its release date, how many votes and so on. My problem starts right here, I want to load usercontrolls as async, so I want all of them loaded in my main window at the same time. But I can't do it, they're loading one by one. Is there a way to use Async in the UI update? Or is there another way to achieve this? I want to get the names of all 20 movie posters at the same time as the webpages and get these 20 usercontrol added to my main window at the same time. I am using this code right now:

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

              }
        }

Even if you don't want to go the whole MVVM route, it's still good practice to separate data access from the UI.

Use an ObservableCollection<> to hold the search results, which will be the driver of the display - this will automatically update any bound controls each time it is refreshed.

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

Your window should use either a ListBox if you want the user to be able to select a specific movie item, otherwise an ItemsControl . In either case, set ItemsSource to the PopularMovies collection. Use a DataTemplate to define the layout for each movie item - each control is bound to the appropriate property of the SearchMovie object.

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

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