Xamarin.Forms图像数据绑定未显示图像

问题描述

数据绑定图像和viewmodel属性不起作用。

但是我根据调试得到了图像流。

我想展示照片。

感谢您的帮助。

查看xaml

<ContentPage.Content>
    <Grid>
        <ScrollView Grid.Row="0">
            <StackLayout>
                <Label Text="Recipe About"/>
                <Entry Placeholder="Title" PlaceholderColor="Olive"
                   Text="{Binding Path=recipe.RecipeName}" />
                <Editor Placeholder="Explanation" PlaceholderColor="Olive" HeightRequest="250"
                    Text="{Binding Path=recipe.Explanation}"/>
                <Image x:Name="RecipeImage"
                   Source="{Binding RecipePhotoSource}"
                        Aspect="AspectFit"/>
                <Button FontFamily="{DynamicResource MaterialFontFamily}"
                    Text="&#xF087c;" FontSize="Large"
                        Command="{Binding PickPhotoCommand}"
                        HorizontalOptions="Center" WidthRequest="100" Margin="0,30" />
...
                </StackLayout>
            </ScrollView>
...
        </Grid>
    </ContentPage.Content>

view.cs

    public RecipeEntryView(RecipeEntryModel recipeEntryModel)
    {
        InitializeComponent();
        var dbService = new DBService(DependencyService.Get<IDbConnection>());
        var pageservice = new PageService();
        BindingContext = new RecipeEntryviewmodel(recipeEntryModel ?? new RecipeEntryModel(),dbService,pageservice); 
    }

vm

public class RecipeEntryviewmodel: Baseviewmodel
    {
        public Recipe recipe { get; private set; }

        public Stream PhotoStream { get;  set; }
        public ImageSource RecipePhotoSource { get;  set; }

...
        public ICommand PickPhotoCommand { get; private set; }

        public RecipeEntryviewmodel(Recipe recipe)
        {
            this.recipe = recipe;
        }

        public RecipeEntryviewmodel(RecipeEntryModel recipeEntryModel,DBService dbService,PageService pageservice)
        {
            if (recipeEntryModel == null)
                throw new ArgumentNullException(nameof(recipeEntryModel));

            this.dbService = dbService;
           this.pageService = pageservice;

            recipe = new Recipe
            {
                RecipeId = recipeEntryModel.EntryRecipeId,RecipeName = recipeEntryModel.RecipeName,Explanation = recipeEntryModel.Explanation,PhotoFilePath = recipeEntryModel.PhotoFilepath,PhotoBytes = recipeEntryModel.PhotoBytes,Items = recipeEntryModel.Items,Steps = recipeEntryModel.Steps
            };

                Items = recipeEntryModel.Items != null ? new ObservableCollection<Item>(recipe.Items) : new ObservableCollection<Item>();
                Steps = recipeEntryModel.Items != null ? new ObservableCollection<Step>(recipe.Steps) : new ObservableCollection<Step>();
    
                RecipePhotoSource = recipeEntryModel.PhotoFileSource ;
    ...
                PickPhotoCommand = new Command(async () => await PickPhoto());
            }
    ...
    
            private async Task PickPhoto()
            {
    
                Stream stream = await DependencyService.Get<IPhotoPickerService>().GetimagestreamAsync();
                if (stream != null)
                {
                    PhotoStream = stream;
                    recipe.PhotoBytes = ImageConversion.GetimageBytes(PhotoStream);
    
                    RecipePhotoSource = ImageSource.FromStream(() => stream);
                    
                }
    
            }
    
    ...
    }

解决方法

我注意到您在BaseViewModel中使用了RecipeEntryViewModel.cs

请将您的public ImageSource RecipePhotoSource { get; set; }代码更改为以下代码。

  ImageSource _recipePhotoSource;
        public ImageSource RecipePhotoSource
        {
            get { return _recipePhotoSource; }
            set { SetValue(ref _recipePhotoSource,value); }
        }

这是我的BaseViewModel代码。

    public abstract class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(
               [CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(
                    this,new PropertyChangedEventArgs(propertyName));
        }

        protected void SetValue<T>(ref T backingField,T value,[CallerMemberName] string propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(
                         backingField,value)) return;
            backingField = value;
            OnPropertyChanged(propertyName);
        }
    }

此处正在运行gif。

enter image description here

从Asset文件夹中读取图像。

[assembly: Dependency(typeof(PhotoPickerService))]
namespace ImageViewModel.Droid
{
    class PhotoPickerService : IPhotoPickerService
    {
        public Stream GetImageStreamAsync()
        {
           
            //throw new NotImplementedException();
            AssetManager assets = Android.App.Application.Context.Assets;

            Stream input = assets.Open("test2.jpg");
            return input;
        }
    }
}
,

感谢吕Leon,我实现了将属性更改为RecipePhotoSource。

ImageSource _recipePhotoSource;
        public ImageSource RecipePhotoSource
        {
            get { return _recipePhotoSource; }
            set { SetValue(ref _recipePhotoSource,value); }
        }

我还需要新的信息流来显示照片。

    private async Task PickPhoto()
    {

        Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
        if (stream != null)
        {
            PhotoBytes = ImageConversion.GetImageBytes(stream);

            recipe.PhotoBytes = PhotoBytes;

            RecipePhotoSource = ImageSource.FromStream(() => ImageConversion.BytesToStream(PhotoBytes));

        }

    }

现在,我可以选择并显示照片。