【发布时间】:2016-06-17 18:10:42
【问题描述】:
我在使用 ui 更新从服务器下载多个图像时遇到问题。问题是我在服务器上有墙纸文件夹并且我想下载图像,我运行后台工作程序来下载图像并更新我的 UI,一旦我的所有图像下载完成(BackgroundWorker_Completed),我的 UI 更新就会完成。但我希望每次下载一个图像文件夹时更新我的 UI,如下图所示。
在上面给出的示例中,每个文件夹都包含多个图像,例如电影、游戏、印度等,并且它们具有所属类别的图像,例如在电影中,它们是文件夹,比如钢铁侠、牧师等。现在,当我下载我的图像时,它们应该在 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);
}
}
}
}
}
【问题讨论】:
-
请提供额外的 XAML 代码。看来您的绑定没有更新,但如果没有 XAML 就很难分辨
-
@lokusking
pnlBackground.Source = image.Source;暗示没有绑定。 -
-
主要问题是您在 RunWorkerCompleted 处理程序中一次创建所有 BitmapImages。另一种方法是在下载后立即创建每个 BitmapImage(在 DoWork 中)。您必须确保在创建期间设置
BitmapCacheOption.OnLoad标志并调用Freeze()方法以使其可跨线程访问。将位图分配给图像控件必须在 UI 线程中完成,例如Dispatcher.Invoke()。除此之外,为pnlBackground.Source = image.Source提供中间图像控件是完全多余的。 -
我建议有一个
ObservableCollection<ImageSource>(通过 Dispatcher 调用更新),并将 ListBox 绑定到该集合。然后在 ListBox 的 ItemTemplate 中声明一个 Image 控件,并将其 Source 属性绑定到集合元素,如<Image Source="{Binding}" />。