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

时间:2016-06-17 09:00:34

标签: c# wpf

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

enter image description here

在上面给出的示例中,每个文件夹包含多个图像,例如电影,游戏,印度等,并且它们具有其所属类别的图像,例如,在电影中,他们的文件夹是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<String> backimage = new List<String>();

            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<string> directories = new List<string>();
            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);
                        }
                    }
                }
            }
        }

1 个答案:

答案 0 :(得分:3)

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

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

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

openstreetmap.org

您可以设置您的MainWindow public class ViewModel { public ObservableCollection<ImageSource> Images { get; private set; } = new ObservableCollection<ImageSource>(); 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)); } } } } } 并在DataContext事件处理程序中开始下载,如下所示:

Loaded

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

public MainWindow()
{
    InitializeComponent();

    var viewModel = new ViewModel();
    DataContext = viewModel;

    Loaded += async (s, e) => await viewModel.DownloadImages();
}