Home > OS >  ObservableCollection overrides all previously added values
ObservableCollection overrides all previously added values

Time:09-17

I'm a Xamarin.Forms beginner and developing a simple picture gallery, where each picture taken by the camera (with Xam.Plugin.Media) gets added to a FlowListView (DLToolkit).

Everything works fine, but as soon as I take more than 1 picture, the last added value overrides all of the previous ones. So instead of multiple different pictures, it's the newest one over and over again.

I've tried changing the ObservableCollection to a regular List, but the problem persists. The overriding happens right after I add the value to the Collection.

Below is my code, maybe one of you can help guide me into the right direction?

ViewModel.cs

        public ViewModel()
        {
            TakePictureCmd = new Command(TakePicture);
            NewPicture = new Model.ImagePicker();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        
        public Model.ImagePicker NewPicture { get; set; }

        public string Path
        {
            get { return NewPicture.ImagePath; }
            set { NewPicture.ImagePath = value; }
        }

        public ObservableCollection<Model.ImagePicker> TakenPicturesList
        {
            get { return Model.ImagePicker.TakenPicturesList; }
            set { Model.ImagePicker.TakenPicturesList = value; OnPropertyChanged(nameof(TakenPicturesList)); }
        }

        public Command TakePictureCmd { get; set; }

        private async void TakePicture()
        {
                var takenPictureTask = await _cameraService.TakePictureAsync();
                Path = takenPictureTask;
                AddPicturesToList(NewPicture);
            
        }

        private void AddPicturesToList(Model.ImagePicker NewPicture)
        {
            TakenPicturesList.Add(NewPicture);
            NewPicture = new Model.ImagePicker();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Path)));
        }  

        public void RaisedOnPropertyChanged(string _PropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_PropertyName));
        }

Model.cs

 public class ImagePicker
    {
        public string ImagePath { get; set; }

        public static ObservableCollection<ImagePicker> TakenPicturesList { get; set; } = new ObservableCollection<ImagePicker>();  
    }

UI

<flv:FlowListView SeparatorVisibility="None" HasUnevenRows="true"
            FlowColumnMinWidth="110" FlowItemsSource="{Binding TakenPicturesList}">

                    <flv:FlowListView.FlowColumnTemplate>
                        <DataTemplate>
                            <Grid Padding="3">

                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>

                                <ffimageloading:CachedImage HeightRequest="100" Aspect="AspectFill"
                            DownsampleHeight="100" DownsampleUseDipUnits="false" 
                            Source="{Binding ImagePath}"/>
                            </Grid>
                        </DataTemplate>
                    </flv:FlowListView.FlowColumnTemplate>

                </flv:FlowListView>

CodePudding user response:

I don't see any utility in your VM having NewPicture or Path properties, or your Model having a TakenPicturesList property. You can probably get rid of those.

TakePicture could then be simplified to this

private async void TakePicture()
{
    var path = await _cameraService.TakePictureAsync();
    TakenPicturesList.Add(new Model.ImagePicker { ImagePath = path});
}

and declare TakenPicturesList like this

public ObservableCollection<Model.ImagePicker> TakenPicturesList { get; set; }

you also need to be sure to initialize TakenPicturesList in the VM constructor, otherwise it will be null

public ViewModel()
{
    TakePictureCmd = new Command(TakePicture);
    TakenPicturesList = new ObservableCollection<Model.ImagePicker>();
}
  • Related