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="󰡼" 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.