0
votes

I have created a custom class named ImageItem which contains a BitmapImage and string to gather the response of the CaptureImageTask. I would like to save each image and its respective path to an ObservableCollection which is bound to a listbox in my view.

As of now the listbox populates correctly, but I am having trouble storing ObservableCollection<ImageItem> in isolated storage, I believe because of the BitmapImage type.

I am not sure of how to fix my solution so that the BitmapImage will be allowed to be saved to isolated storage along with its respective path within an ObservableCollection.

I believe I have narrowed down the issue to BitmapImage not being a serializable type. I have tried using [DataContract] and '[DataMember]attributes withinImageItem.cs` without success. I have never attempted to save a nonprimitive type.

Following are the code, with some description of each file.

  • ImageItem.cs

    public class ImageItem
    {
        public BitmapImage ImageUri
        {
            get;
            set;
        }
    
        public string ImagePath
        {
            get;
            set;
        }
    }
    
  • Settings.cs

    I am using a Settings class to create the ObservableCollection of custom type.

    public static class Settings
    {
        public static readonly Setting<ObservableCollection<ImageItem>> imageList = new Setting<ObservableCollection<ImageItem>>("imageList", new ObservableCollection<ImageItem>());
    }
    
  • Setting.cs

    Where Setting is a class that reads and saves data to Isolated Storage

    public class Setting<T>
    {
        string name;
        T value;
        T defaultValue;
        bool hasValue;
    
        public Setting(string name, T defaultValue)
        {
            this.name = name;
            this.defaultValue = defaultValue;
        }
    
        public T Value
        {
            get
            {
                //Check for the cached value
                if (!this.hasValue)
                {
                    //Try to get the value from Isolated Storage
                    if (!IsolatedStorageSettings.ApplicationSettings.TryGetValue(this.name, out this.value))
                    {
                        //It hasn't been set yet
                        this.value = this.defaultValue;
                        IsolatedStorageSettings.ApplicationSettings[this.name] = this.value;
                    }
                    this.hasValue = true;
                }
                return this.value;
            }
    
            set
            {
                //Save the value to Isolated Storage
                IsolatedStorageSettings.ApplicationSettings[this.name] = value;
                this.value = value;
                this.hasValue = true;
            }
        }
    
        public T DefaultValue
        {
            get { return this.defaultValue; }
        }
    
        // Clear cached value
        public void ForceRefresh()
        {
            this.hasValue = false;
        }
    }
    
  • MainPage.xaml.cs

    From here I am simply attempting to save the result of the CameraCaptureTask which is used to populate the ObservableCollection and the listbox

    void cameraCaptureTask_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            //values declared earlier
            imgChosenPhotoFilePath = null;
            bmp = new BitmapImage();
    
            imgChosenPhotoFilePath = e.OriginalFileName;
    
            bmp.SetSource(e.ChosenPhoto);
            imgChosenPhoto.Source = bmp;
    
            //Add photo to listbox and observablecollection
            AddToImgList(imgChosenPhotoFilePath, bmp);
        }
    }
    
    private void AddToImgList(string filePath, BitmapImage bitmap)
    {
        //save the values to the ObservableCollection
        Settings.imageList.Value.Add(new ImageItem() { ImagePath = filePath, ImageUri = bitmap });
    
        //populate the listbox in the view named imgList
        imgList.ItemsSource = Settings.imageList.Value;
    }
    
1

1 Answers

0
votes

As you've discovered, you can't serialize the BitmapImage. The simplest alternative would be to save this as a separate file and then save the name of the file in the collection you're serializing.

Obviously, when deserializing, you'll need to read the file from disk and load it back into a BitmapImage.

If you're persisting this data for use across the lifetime of the app it'll probably be easier to just save the images straight to IsolatedStorage and keep the paths in your view model. You can then bind the path to an Image in the ListBoxItemTemplate.