我在使用 ui 更新从服务器下载多个图像时遇到问题。问题是我在服务器上有壁纸文件夹并且我想下载图像,我运行后台工作程序来下载图像并更新我的 UI,一旦我的所有图像都下载完成(BackgroundWorker_Completed),我的 UI 更新就会完成。但是我希望每次下载一个图像文件夹时更新我的 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
{
}
}
后台 worker 已完成在 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 中显示它们,请查看以下简化的 View 模型,它为所有下载的图像声明一个集合属性和一个 async
执行下载的方法。
下载是异步的,因为该方法调用(并等待)异步 HttpClient.GetByteArrayAsync()
方法。
为了演示,它从 openstreetmap.org
下载 256 张( map 图 block )图像。
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
事件处理程序中开始下载,如下所示:
public MainWindow()
{
InitializeComponent();
var viewModel = new ViewModel();
DataContext = viewModel;
Loaded += async (s, e) => await viewModel.DownloadImages();
}
最后,ListBox 的 XAML 可能如下所示:
<ListBox ItemsSource="{Binding Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
关于c# - 如何在 Wpf 中下载内容和更新 UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37877316/