ObservableCollection associated with ViewModel does not refresh view

I allow the user to delete the item through the ContextMenu menu item in the view, and I would like the effect to appear automatically in the view. At the moment, the element in the view remains until the application is restarted, in which case it will no longer be visible. This is very confusing for the user who believes that the item is completely removed from the application. My question is: what am I doing wrong to solve this problem?

App.xaml.cs

//PictureRepository is a class that gathers pictures from IsolatedStorage public static PictureRepository PictureList { get { return PictureRepository.Instance; } } 

PictureRepository.cs

 #region Constants public const string IsolatedStoragePath = "Pictures"; #endregion #region Fields private readonly ObservableCollection<Picture> _pictures = new ObservableCollection<Picture>(); #endregion #region Properties public ObservableCollection<Picture> Pictures { get { return _pictures; } } #endregion #region Singleton Pattern private PictureRepository() { LoadAllPicturesFromIsolatedStorage(); } public static readonly PictureRepository Instance = new PictureRepository(); #endregion /// <summary> /// Saves to local storage /// This method gets two parameters: the captured picture instance and the name of the pictures folder in the isolated storage /// </summary> /// <param name="capturedPicture"></param> /// <param name="directory"></param> public void SaveToLocalStorage(CapturedPicture capturedPicture, string directory) { //call IsolatedStorageFile.GetUserStoreForApplication to get an isolated storage file var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Call the IsolatedStorageFile.EnsureDirectory extension method located in the Common IsolatedStorageFileExtensions class to confirm that the pictures folder exists. isoFile.EnsureDirectory(directory); //Combine the pictures folder and captured picture file name and use this path to create a new file string filePath = Path.Combine(directory, capturedPicture.FileName); using (var fileStream = isoFile.CreateFile(filePath)) { using (var writer = new BinaryWriter(fileStream)) { capturedPicture.Serialize(writer); } } } /// <summary> /// To load all saved pictures and add them to the pictures list page /// </summary> public CapturedPicture LoadFromLocalStorage(string fileName, string directory) { //To open the file, add a call to the IsolatedStorageFile.GetUserStoreForApplication var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Combine the directory and file name string filePath = Path.Combine(directory, fileName); //use the path to open the picture file from the isolated storage by using the IsolatedStorageFile.OpenFile method using (var fileStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read)) { //create a BinaryReader instance for deserializing the CapturedPicture instance using (var reader = new BinaryReader(fileStream)) { var capturedPicture = new CapturedPicture(); //create a new instance of the type CapturedPicture called CapturedPicture.Deserialize to deserialize the captured picture and return it capturedPicture.Deserialize(reader); return capturedPicture; } } } /// <summary> /// To load all the pictures at start time /// </summary> private void LoadAllPicturesFromIsolatedStorage() { //add call to the IsolatedStorageFile.GetUserStoreForApplication to open an isolated storage file var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Call the IsolatedStorageFile.EnsureDirectory extension method located in the Common IsolatedStorageFileExtensions class to confirm that the pictures folder exists isoFile.EnsureDirectory(IsolatedStoragePath); //Call the IsolatedStorageFile.GetFileNames using the pictures directory and *.jpg as a filter to get all saved pictures var pictureFiles = isoFile.GetFileNames(Path.Combine(IsolatedStoragePath, "*.jpg")); //var pictureFiles = isoFile.GetFileNames(Path.Combine(IsolatedStoragePath, "")); //Iterate through all the picture files in the list and load each using the LoadFromLocalStorage you created earlier foreach (var pictureFile in pictureFiles) { var picture = LoadFromLocalStorage(pictureFile, IsolatedStoragePath); _pictures.Add(picture); } } 

MainPage.xaml.cs

 protected override void OnNavigatedTo(NavigationEventArgs e) { //Recent is the ListBox in the view that is populated from the ObservableCollection if (Settings.AscendingSort.Value) { //Recent.ItemsSource = PictureRepository.Instance.Pictures.OrderBy(x => x.DateTaken); Recent.ItemsSource = App.PictureList.Pictures.OrderBy(x => x.DateTaken); } else { //Recent.ItemsSource = PictureRepository.Instance.Pictures.OrderByDescending(x => x.DateTaken); Recent.ItemsSource = App.PictureList.Pictures.OrderByDescending(x => x.DateTaken); } } //My attempt at deleting the item from both the View and IsolatedStorage private void deleteContextMenuItem_Click(object sender, RoutedEventArgs e) { var listBoxItem = ((MenuItem)sender).DataContext as CapturedPicture; fileName = listBoxItem.FileName; if (fileName != null) { try { //Neither of the following remove the item from the View immediately App.PictureList.Pictures.Remove(listBoxItem); PictureRepository.Instance.Pictures.Remove(listBoxItem); //To open the file, add a call to the IsolatedStorageFile.GetUserStoreForApplication var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Combine the directory and file name string filePath = Path.Combine(PictureRepository.IsolatedStoragePath, fileName); isoFile.DeleteFile(filePath); } catch { MessageBoxResult r = MessageBox.Show("There was an error deleting the image.", "Notice", MessageBoxButton.OK); if (r == MessageBoxResult.OK) return; } } } 

As you can see, I am trying to remove an item from View and IsolatedStorage. At the moment, removing from IsolStorage works, but I can't get the view to automatically refresh. I need to wait until the application is restarted and the ListBox will be re-populated in the OnNavigatedTo event to see any changes.

+1
source share
1 answer

The problem is that you are assigning IOrderedEnumerable to Recent.ItemSource, not an ObservableCollection.

In LoadAllPicturesFromIsolatedStorage (), create a temporary list to which you add the loaded data from your file, and then create an ObservableCollection.

PictureRepository.cs

 #region Constants public const string IsolatedStoragePath = "Pictures"; #endregion #region Properties public ObservableCollection<Picture> Pictures { get; private set; } #endregion #region Singleton Pattern private PictureRepository() { LoadAllPicturesFromIsolatedStorage(); } public static readonly PictureRepository Instance = new PictureRepository(); #endregion /// <summary> /// Saves to local storage /// This method gets two parameters: the captured picture instance and the name of the pictures folder in the isolated storage /// </summary> /// <param name="capturedPicture"></param> /// <param name="directory"></param> public void SaveToLocalStorage(CapturedPicture capturedPicture, string directory) { //call IsolatedStorageFile.GetUserStoreForApplication to get an isolated storage file var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Call the IsolatedStorageFile.EnsureDirectory extension method located in the Common IsolatedStorageFileExtensions class to confirm that the pictures folder exists. isoFile.EnsureDirectory(directory); //Combine the pictures folder and captured picture file name and use this path to create a new file string filePath = Path.Combine(directory, capturedPicture.FileName); using (var fileStream = isoFile.CreateFile(filePath)) { using (var writer = new BinaryWriter(fileStream)) { capturedPicture.Serialize(writer); } } } /// <summary> /// To load all saved pictures and add them to the pictures list page /// </summary> public CapturedPicture LoadFromLocalStorage(string fileName, string directory) { //To open the file, add a call to the IsolatedStorageFile.GetUserStoreForApplication var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Combine the directory and file name string filePath = Path.Combine(directory, fileName); //use the path to open the picture file from the isolated storage by using the IsolatedStorageFile.OpenFile method using (var fileStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read)) { //create a BinaryReader instance for deserializing the CapturedPicture instance using (var reader = new BinaryReader(fileStream)) { var capturedPicture = new CapturedPicture(); //create a new instance of the type CapturedPicture called CapturedPicture.Deserialize to deserialize the captured picture and return it capturedPicture.Deserialize(reader); return capturedPicture; } } } /// <summary> /// To load all the pictures at start time /// </summary> private void LoadAllPicturesFromIsolatedStorage() { //add call to the IsolatedStorageFile.GetUserStoreForApplication to open an isolated storage file var isoFile = IsolatedStorageFile.GetUserStoreForApplication(); //Call the IsolatedStorageFile.EnsureDirectory extension method located in the Common IsolatedStorageFileExtensions class to confirm that the pictures folder exists isoFile.EnsureDirectory(IsolatedStoragePath); //Call the IsolatedStorageFile.GetFileNames using the pictures directory and *.jpg as a filter to get all saved pictures var pictureFiles = isoFile.GetFileNames(Path.Combine(IsolatedStoragePath, "*.jpg")); //var pictureFiles = isoFile.GetFileNames(Path.Combine(IsolatedStoragePath, "")); var pictures = new List<Picture>(); //Iterate through all the picture files in the list and load each using the LoadFromLocalStorage you created earlier foreach (var pictureFile in pictureFiles) { var picture = LoadFromLocalStorage(pictureFile, IsolatedStoragePath); pictures.Add(picture); } Pictures = new ObservableCollection<Picture>(pictures.OrderBy(x => x.DateTaken)); } 

On MainPage.cs change the OnNavigatedTo method to:

 protected override void OnNavigatedTo(NavigationEventArgs e) { //Recent is the ListBox in the view that is populated from the ObservableCollection //Recent.ItemsSource = PictureRepository.Instance.Pictures.OrderBy(x => x.DateTaken); Recent.ItemsSource = App.PictureList.Pictures; } 
+1
source

Source: https://habr.com/ru/post/950833/


All Articles