Reputation: 4427
I have an ObservableCollection
that holds the items for a ListView
.
ObservableCollection<MyListItem> Items { get; set; }
During item creation an image path is pulled from cache.
public class MyListItem {
public string Image { get; set; }
public MyListItem(string url) {
...
setImage(url);
}
private async void setImage(string url) {
Image = await MyCachingLib.GetUrlAsync(url);
}
}
However, if the image isn't already in cache, we download it from the internet. This takes too long and the UI seems to have already updated by the time Image is set.
How can I update my ListView each time an Item is done fetching an image?
I tested to make sure its not my caching library with this:
private async void setTitle(string title) {
await Task.Delay(2000); //pretend to get data from the web
Title = title;
}
...And the title doesn't update with the delay.
Upvotes: 0
Views: 409
Reputation: 3053
Another way is to make your class derive from BindableObject
, so that you can do this:
public class MyListItem : BindableObject {
public string Image { get; set; }
public MyListItem(string url) {
...
setImage(url);
}
private async void setImage(string url) {
Image = await MyCachingLib.GetUrlAsync(url);
OnPropertyChanged(nameof(Image));
}
}
The added line will do just what you want, signal that Image was updated without having to implement a full property.
Upvotes: 0
Reputation: 599
Make your MyListItem
implement INotifyPropertyChanged
. With that approach, changes will be propagated to the UI.
public class MyListItem : BaseModel
{
private string image;
public string Image
{
get => image;
set
{
image = value;
OnPropertyChanged(nameof(Image));
}
}
public MyListItem(string url)
{
...
setImage(url);
}
private async void setImage(string url)
{
Image = await MyCachingLib.GetUrlAsync(url);
}
}
public abstract class BaseModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
changed?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I've done it with BaseModel
but you can freely put INotifyImplementation
in your model.
In your Xaml/UI file, just bind to Image. It should work ;-)
Upvotes: 1