使用异步数据时在 Xamarin 中绑定图像源

Binding image source in Xamarin when using async data

我正在努力将图像源设置为我从数据库收到的值。 以下是我的 XAML、其代码隐藏和视图模型的相关部分。

XAML:

<Label Text="{Binding ViewModel_Fid}" />
<Image Source="{Binding ViewModel_ImageStream}" />

代码隐藏:

protected override void OnAppearing() {
            base.OnAppearing();
            myViewModel = new myViewModel();

            myViewModel.PopulateFid();
            BindingContext = myViewModel;
        }

查看模型:

public event PropertyChangedEventHandler PropertyChanged;
private string _fid;

public async void PopulateFid() {
            _fid = await getFid();
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(ViewModel_Fid)));
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(ViewModel_ImageStream)));

public MemoryStream ViewModel_ImageStream { 
            get {
                byte[] buffer = myGetBytes(_fid);
                return null == buffer ? null : new MemoryStream(buffer);    
            } 
        }

问题是,ViewModel_ImageStream 在 PopulateFid 之前系统地执行,这意味着在 ViewModel_ImageStream 中我总是得到 _fid = null。 我很确定这是因为 PopulateFid 是异步的,但我需要这样,因为 getFid() 是一个外部异步函数。

如何强制 PopulateFid 在设置 ViewModel_ImageStream 之前执行?

谢谢!

PS。请参阅下面我的 solution/answer。

最终对我有用的是在运行时添加图像元素(即不在 XAML 中指定)。 我在视图模型中检索到必要数据后添加它。

因此在代码隐藏中:

protected override void OnAppearing() {
            base.OnAppearing();
            myViewModel = new myViewModel();

            myViewModel.PopulateFid();
            BindingContext = myViewModel;
            myViewModel.LoadImage = (obj) => {
                var img = new Image();
                img.Source = new StreamImageSource() {
                    Stream = (token) => getstream(token)
                };
                mainstack.Children.Add(img);
            };
        }

private async Task<Stream> getstream(object token) {
            return new MemoryStream(myViewModel.myGetBytes);
        }

在视图模型中:

private string _fid;

public async void PopulateFid() {
            _fid = await getFid();
            LoadImg?.Invoke(true);
}