如何在Wpf中下载内容并更新UI? [英] How to download content and update UI in Wpf?

查看:66
本文介绍了如何在Wpf中下载内容并更新UI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having an issue in downloading multiple image from server with ui updation. Problem is this that I have folders of wallpaper on server and I want to download images, I run a background worker to download images and to update my UI and my UI updation will be done once my all images gets downloaded(BackgroundWorker_Completed). But I want my UI to be updated every time when one folder of images gets downloaded as shown in below given image.

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

In above given example every folder contains multiple images such as Movies, Games, India etc and they have images of their belonging category e.g. in movies their are folders say Man Of Steel, Priest etc. Now when I am downloading my images they should be visible on UI every they gets downloads not in once at last. Code for downloading wallpaper given below:

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

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


推荐答案

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

To get an idea of how one could asynchronously download a large number of images while simultaneously showing them in a ListBox, take a look at the following simplified view model, which declares a collection property for all downloaded images and an async method that performs the download.

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

The download is asynchronous because the method calls (and awaits) the async HttpClient.GetByteArrayAsync() method.

为进行演示,它下载了256(地图tile)来自 openstreetmap.org 的图像。

For demonstration, it downloads 256 (map tile) images from openstreetmap.org.

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

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

You may set up your MainWindow's DataContext and start the download in a Loaded event handler like this:

public MainWindow()
{
    InitializeComponent();

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

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

最后,ListBox的XAML可能看起来像这样:

Finally, the ListBox's XAML might look like this:

<ListBox ItemsSource="{Binding Images}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这篇关于如何在Wpf中下载内容并更新UI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆