异步方法后更新Listview

时间:2019-10-28 18:46:26

标签: c# xamarin

我有一个ObservableCollection,其中存放着ListView的物品。

ObservableCollection<MyListItem> Items { get; set; }

在创建项目期间,会从缓存中提取图像路径。

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

但是,如果图像尚未在缓存中,我们将从互联网上下载它。这花费的时间太长,并且在设置Image时,UI似乎已经更新。

每次完成获取图像后,如何更新ListView?

我进行了测试,以确保它不是我的缓存库:

private async void setTitle(string title) {
   await Task.Delay(2000); //pretend to get data from the web
   Title = title;
}

...并且标题没有随时间更新。

2 个答案:

答案 0 :(得分:1)

使您的MyListItem实施INotifyPropertyChanged。通过这种方法,更改将被传播到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));
    }
}

我已经用BaseModel完成了操作,但是您可以将INotifyImplementation自由地放入模型中。

在您的Xaml / UI文件中,只需绑定到Image。它应该可以工作;-)

答案 1 :(得分:0)

另一种方法是使您的类从BindableObject派生,以便您可以执行此操作:

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

添加的行将按您想要的做,表明Image已更新,而无需实现完整属性。