我想在cell.ImageView.Image
控制器的UITableView
方法中将网址中的图片显示为GetCell
变量。出于某种原因,仅当我单击单元格时才会显示图像。它正在获取图像,但是单元格没有被更新。数据是ObservableCollection
,所以我不确定我缺少什么。我是否需要明确调用任何方法?
public class PasswordGroupsDataSource : UITableViewDataSource
{
const string PlaceholderImagePath = "Placeholder.jpg";
UIImage PlaceholderImage { get; set; }
PasswordsViewController Controller { get; set; }
List<Password> Apps;
public ObservableCollection<PasswordGroup> Groups { get; set; }
public PasswordGroupsDataSource(ObservableCollection<PasswordGroup> groups, PasswordsViewController controller, List<Password> passwords)
{
Controller = controller;
Apps = passwords;
PlaceholderImage = UIImage.FromFile("Images/Placeholder.png");
if (groups == null)
{
throw new ArgumentNullException("groups");
}
Groups = groups;
groups.CollectionChanged += HandleAppsCollectionChanged;
// If either a download fails or the image we download is corrupt, ignore the problem.
TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e)
{
e.SetObserved();
};
}
void HandleAppsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Whenever the Items change, reload the data.
Controller.TableView.ReloadData();
}
public Password GetPerson(NSIndexPath indexPath)
{
try
{
var personGroup = Groups[indexPath.Section];
return personGroup.People[indexPath.Row];
}
catch (Exception exc)
{
Console.WriteLine("Error in GetPerson: " + exc.Message);
//Occasionally we get an index out of range here
return null;
}
}
public override string TitleForHeader(UITableView tableView, nint section)
{
return Groups[(int)section].Title;
}
public override string[] SectionIndexTitles(UITableView tableView)
{
return Groups.Select(x => x.Title).ToArray();
}
public override nint NumberOfSections(UITableView tableView)
{
return Groups.Count;
}
public override nint RowsInSection(UITableView tableView, nint section)
{
return Groups[(int)section].People.Count;
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
var cell = tableView.DequeueReusableCell("P") as PasswordCell;
if (cell == null)
{
cell = new PasswordCell("P");
}
var person = GetPerson(indexPath);
cell.Tag = indexPath.Row;
if (person != null)
{
cell.Person = person;
if (person.Image == null)
{
person.Image = PlaceholderImage;
BeginDownloadingImage(person, indexPath);
}
cell.ImageView.Image = person.Image;
}
return cell;
}
#region Image Support
readonly Dictionary<string, UIImage> images = new Dictionary<string, UIImage>();
readonly List<string> imageDownloadsInProgress = new List<string>();
readonly ImageDownloader imageDownloader = new UIKitImageDownloader();
async void BeginDownloadingImage(Password app, NSIndexPath path)
{
// Queue the image to be downloaded. This task will execute
// as soon as the existing ones have finished.
byte[] data = null;
data = await GetImageData(app.GravatarUrl.ToString());
app.Image = UIImage.LoadFromData(NSData.FromArray(data));
InvokeOnMainThread(() =>
{
if (Apps != null)
{
var cell = Controller.TableView.VisibleCells.Where(c => c.Tag == Apps.IndexOf(app)).FirstOrDefault();
if (cell != null)
cell.ImageView.Image = app.Image;
}
});
}
async Task<byte[]> GetImageData(string ImageUrl)
{
byte[] data = null;
try
{
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
using (var c = new GzipWebClient())
data = await c.DownloadDataTaskAsync(ImageUrl);
}
finally
{
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false;
}
return data;
}
public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
{
return true;
}
public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
{
if (editingStyle == UITableViewCellEditingStyle.Delete)
{
Groups.RemoveAt(indexPath.Row);
}
}
#endregion
}
当我调试它时,我可以看到图像是在BeginDownloadingImage
函数中设置的。我错过了什么?为什么在单击单元格之前单元格没有更新?
注意:我使用的是Xamarin员工目录样本。
答案 0 :(得分:0)
我不确定你能这样做。我会覆盖Person对象上的占位符Image,然后从tableview中调用ReloadRows。
InvokeOnMainThread(() =>
{
if (Apps != null)
{
person.Image = app.Image;
Controller.TableView.ReloadRows (new NSIndexPath[]{ path }, UITableViewRowAnimation.Fade);
}
});