Search code examples
c#windowswindows-phone-8isolatedstorage

Using IsolatedStorageSettings to store information permanently for an app in wp8


I am using IsolatedStorageSettings to store a contact list for a key in my app. But the app only stores the list till the app is active(i.e. like navigating from one page to another). If I exit the app and again relaunch it, the stored key/contact list is not found. How do i permanently save a list for an app, till the app is installed? Here is the code of my viewmodel, I am using:

   public class ContactsViewModel : ViewModelBase
    {
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
        private List<SavedContact> _SavedContactsList;
        public ContactsViewModel()
        {

            Contacts cons = new Contacts();
            cons.SearchAsync(String.Empty, FilterKind.None, null);
            cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(OnContactSearchCompleted);
            SaveSavedContactsCommand = new RelayCommand(OnSaveSavedContacts);
        }


        private List<SavedContact> GetSavedContacts()
        {

            if (appSettings.Contains("SavedContacts"))
            {
                var savedContacts = (List<SavedContact>)appSettings["SavedContacts"];
                return savedContacts;
            }
            else
            {
                return new List<SavedContact>();
            }
        }
        public RelayCommand SaveSavedContactsCommand { get; set; }

        private void OnSaveSavedContacts()
        {
            if (!SavedContactsList.Any(x => x.IsSelected == true))
            {
                MessageBox.Show("Please select some contacts and then click on Save button.");
            }
            else
            {
                var selectedSavedContacts = SavedContactsList.Where(x => x.IsSelected == true).ToList();
                SavedContacts = selectedSavedContacts;
                MessageBox.Show("Emergency contact list added successfully.");

                App.RootFrame.GoBack();
            }
        }

        void OnContactSearchCompleted(object sender, ContactsSearchEventArgs e)
        {
            try
            {
                SavedContactsList = new List<SavedContact>();
                var allContacts = new List<Contact>(e.Results.Where(x => x.PhoneNumbers.Count() > 0).OrderBy(c => c.DisplayName));
                // var savedContacts = GetSavedContacts();
                var savedContacts = SavedContacts;
                foreach (Contact contact in allContacts)
                {
                    SavedContact SavedContact = new SavedContact() { Contact = contact };
                    if (savedContacts.Any(x => x.Contact.PhoneNumbers.ElementAt(0).PhoneNumber == contact.PhoneNumbers.ElementAt(0).PhoneNumber))
                    {
                        SavedContact.IsSelected = true;
                    }
                    else
                    {
                        SavedContact.IsSelected = false;
                    }
                    SavedContactsList.Add(SavedContact);
                }

            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error in retrieving contacts : " + ex.Message);
            }

        }

        [DataMember]
        public List<SavedContact> SavedContactsList
        {
            get { return _SavedContactsList; }
            set
            {
                _SavedContactsList = value;
                RaisePropertyChanged("SavedContactsList");
            }
        }
        private List<SavedContact> SavedContacts
        {
            get
            {
                if (appSettings.Contains("SavedContacts"))
                {
                    var savedContacts = (List<SavedContact>)appSettings["SavedContacts"];
                    return savedContacts;
                }
                else
                {
                    return new List<SavedContact>();
                }
            }
            set
            {
                appSettings["SavedContacts"] = value;
            }
        }


    }

And the class SavedContact is followings:

  [DataContract]
    public class SavedContact : INotifyPropertyChanged
    {
        public SavedContact() { }
        private bool _isSelected;
        private Contact _contact;

        [DataMember]
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }

            }
        }

        [DataMember]
        public Contact Contact
        {
            get
            {
                return _contact;
            }
            set
            {
                if (_contact != value)
                {
                    _contact = value;
                    OnPropertyChanged("Contact");
                }

            }
        }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Where the view model is bound to a <toolKit: LongListMultiSelector />. The functionality is like, I select some contacts from my longlist multiselector and save it in storage to reuse it later. But if I exit the app and restarts it , the savedContacts returns null. While I navigate other pages in my app, the savedContacts is getting printed. If I save a list first time , on app relaunch GetSavedContacts() returns a new list.


Solution

  • The problem isn't related to IsolatedStorageSettings or your RelayCommand. Looking in more detail the problem is with serialization and de-serialization of the Contact object. If you update your implementation to something like the example below, you should be fine.

    public class ContactsViewModel : ViewModelBase
    {
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
    
        private List<UserContact> _contactList;
    
        public ContactsViewModel()
        {
    
            Contacts cons = new Contacts();
            cons.SearchAsync(String.Empty, FilterKind.None, null);
            cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(OnContactSearchCompleted);
            SaveSavedContactsCommand = new RelayCommand(OnSaveSavedContacts);
        }
    
        public RelayCommand SaveSavedContactsCommand { get; private set; }
    
        private void OnSaveSavedContacts()
        {
            if (!Contacts.Any(x => x.IsSelected == true))
            {
                MessageBox.Show("Please select some contacts and then click on Save button.");
            }
            else
            {
                var selectedSavedContacts = Contacts.Where(x => x.IsSelected == true).Select(x => new SavedContact{ Name = x.Contact.DisplayName, PhoneNumber = x.Contact.PhoneNumbers.ElementAt(0).PhoneNumber}).ToList();
                SavedContacts = selectedSavedContacts;
                MessageBox.Show("Emergency contact list added successfully.");
    
                App.RootFrame.GoBack();
            }
        }
    
        void OnContactSearchCompleted(object sender, ContactsSearchEventArgs e)
        {
            try
            {
                Contacts = new List<UserContact>();
                var allContacts = new List<Contact>(e.Results.Where(x => x.PhoneNumbers.Count() > 0).OrderBy(c => c.DisplayName));
    
                foreach (Contact contact in allContacts)
                {
                    UserContact SavedContact = new UserContact() { Contact = contact };
                    if (SavedContacts.Any(x => x.PhoneNumber == contact.PhoneNumbers.ElementAt(0).PhoneNumber))
                    {
                        SavedContact.IsSelected = true;
                    }
                    else
                    {
                        SavedContact.IsSelected = false;
                    }
                    Contacts.Add(SavedContact);
                }
    
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error in retrieving contacts : " + ex.Message);
            }
    
        }
    
        [DataMember]
        public List<UserContact> Contacts
        {
            get { return _contactList; }
            set
            {
                _contactList = value;
                RaisePropertyChanged("Contacts");
            }
        }
    
        public List<SavedContact> SavedContacts
        {
            get
            {
                if (appSettings.Contains("SavedContacts"))
                {
                    var savedContacts = (List<SavedContact>)IsolatedStorageSettings.ApplicationSettings["SavedContacts"];
                    return savedContacts;
                }
                else
                {
                    return new List<SavedContact>();
                }
            }
            set
            {
                if (value != null)
                {
                    IsolatedStorageSettings.ApplicationSettings["SavedContacts"] = value;
                    IsolatedStorageSettings.ApplicationSettings.Save();
                }
            }
        }
    }
    
    public class SavedContact
    {
        public string Name { get; set; }
    
        public string PhoneNumber { get; set; }
    }
    
    [DataContract]
    public class UserContact : INotifyPropertyChanged
    {
        public UserContact() { }
        private bool _isSelected;
        private Contact _contact;
    
        [DataMember]
        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
    
            }
        }
    
        [DataMember]
        public Contact Contact
        {
            get
            {
                return _contact;
            }
            set
            {
                if (_contact != value)
                {
                    _contact = value;
                    OnPropertyChanged("Contact");
                }
    
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }