如何在Wpf中下载内容和更新UI?

我在使用ui更新从服务器下载多个图像时遇到问题。 问题是,我在服务器上有壁纸文件夹,我想下载图像,我运行后台工作程序下载图像并更新我的UI,我的UI更新将在我的所有图像下载后完成(BackgroundWorker_Completed)。 但是我希望每次下载一个图像文件夹时都会更新我的UI,如下图所示。

在此处输入图像描述

在上面给出的示例中,每个文件夹包含多个图像,例如电影,游戏,印度等,并且它们具有其所属类别的图像,例如在电影中它们是文件夹,例如Man Of Steel,Priest等。现在,当我下载我的图像时,它们应该是可见的在UI上,他们每次下载都不是最后一次。 下载壁纸代码如下:


用于下载图像的后台工作器代码

void worker_DoWork(object sender, DoWorkEventArgs e) { try { DataSet dsFile = Global.ReadConfig; XDocument xDoc = XDocument.Load(dsFile.Tables[0].Rows[0][8].ToString()); string s = xDoc.Root.Name.ToString(); var countNode = xDoc.Root.Elements().Count(); for (int i = 0; i < countNode; i++) { XNode childNode = xDoc.Root.Nodes().ElementAt(i); XElement ele = (XElement)childNode; string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Wallpaper\\" + ele.Name; var movieList = from a in xDoc.Root.Descendants(ele.Name).Elements() select a; foreach (var a in movieList) { string newpath = path + "\\" + a.Value; DirectoryInfo di = new DirectoryInfo(newpath); if (!di.Exists) { DirectoryInfo dinew = Directory.CreateDirectory(newpath); filedownload(dsFile.Tables[0].Rows[0][1].ToString() + "/Wallpaper/" + ele.Name + "/" + dinew.Name + "/", newpath + "\\"); } } //new DesktopThemes.App_Page.MainWindow().getWallLink(ele.Name.LocalName); } } catch { } } 

背景工作者完成在UI上显示图像

 void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { string N = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\Wallpaper\" ; Random random = new Random(); List backimage = new List(); DirectoryInfo diback = new DirectoryInfo(N); // diback.GetFiles(); Directory.GetFiles(N, "*.*", SearchOption.AllDirectories); foreach (var imagename in diback.GetFiles("*.jpg", SearchOption.AllDirectories)) { backimage.Add(imagename.Directory + "\\" + imagename.Name); } try { Image image = new Image(); Uri add = new Uri(backimage[random.Next(0, backimage.Count - 1)]); image.Source = new BitmapImage(add); pnlBackground.Source = image.Source; this.Photos.Path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"Wallpaper\"; } catch (Exception ex) { } } 

代码用于下载从后台工作人员调用的图像

  public static void filedownload(String url, string downloadlocation) { FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(url); ftpRequest.Credentials = new NetworkCredential(@username, @password); ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse(); StreamReader streamReader = new StreamReader(response.GetResponseStream()); List directories = new List(); string line = streamReader.ReadLine(); while (!string.IsNullOrEmpty(line)) { directories.Add(line); line = streamReader.ReadLine(); } streamReader.Close(); using (WebClient ftpClient = new WebClient()) { ftpClient.Credentials = new System.Net.NetworkCredential(@username, @password); for (int i = 0; i <= directories.Count - 1; i++) { if (directories[i].Contains(".")) { string path = url + directories[i].ToString(); string trnsfrpth = downloadlocation + directories[i].ToString(); if (!new System.IO.FileInfo(trnsfrpth).Exists) { ftpClient.DownloadFile(path, trnsfrpth); } } } } } 

要了解如何异步下载大量图像,同时在ListBox中显示它们,请查看以下简化视图模型,该模型声明所有下载图像的集合属性和执行下载的async方法。

下载是异步的,因为该方法调用(并等待)异步HttpClient.GetByteArrayAsync()方法。

为了演示,它从openstreetmap.org下载256(地图图块)图像。

 public class ViewModel { public ObservableCollection Images { get; private set; } = new ObservableCollection(); public async Task DownloadImages() { var httpClient = new HttpClient(); for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { var url = string.Format( "http://tile.openstreetmap.org/4/{0}/{1}.png", x, y); // the await here makes the download asynchronous var buffer = await httpClient.GetByteArrayAsync(url); using (var stream = new MemoryStream(buffer)) { Images.Add(BitmapFrame.Create( stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad)); } } } } } 

您可以设置MainWindow的DataContext并在Loaded事件处理程序中开始下载,如下所示:

 public MainWindow() { InitializeComponent(); var viewModel = new ViewModel(); DataContext = viewModel; Loaded += async (s, e) => await viewModel.DownloadImages(); } 

最后,ListBox的XAML可能如下所示: