简体   繁体   中英

Xamarin.Forms Image DataBinding not show Image

Data Binding Image and ViewModel property is not working.

But I got image stream according to debugging .

I want to show photo.

I am grateful for any help.

view 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,0,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);
                    
                }
    
            }
    
    ...
    }

I notice you used BaseViewModel in RecipeEntryViewModel.cs

Please change your public ImageSource RecipePhotoSource { get; set; } public ImageSource RecipePhotoSource { get; set; } public ImageSource RecipePhotoSource { get; set; } code to following code.

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

Here is my BaseViewModel code.

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

Here is running gif.

在此处输入图片说明

Read the Image from Asset folder.

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

Thanks for Leon Lu , I implemented propertychanged to RecipePhotoSource.

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

And I also need new stream to show photo.

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

        }

    }

Now, I can pick and show photo.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM