При закрытии формы "не успевают" сохраниться настройки - C#

Узнай цену своей работы

Формулировка задачи:

MainWindow.xaml.cs

Листинг программы
  1. using System.Windows;
  2. using Wpf_TimeRandomizer.ViewModel;
  3. namespace Wpf_TimeRandomizer
  4. {
  5. public partial class MainWindow : Window
  6. {
  7. public MainWindow()
  8. {
  9. InitializeComponent();
  10. Closing += (s, e) => ViewModelLocator.Cleanup();
  11. }
  12. }
  13. }

MainViewModel.cs

Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Threading;
  6. using Wpf_TimeRandomizer.Model;
  7. namespace Wpf_TimeRandomizer.ViewModel
  8. {
  9. public class MainViewModel : ViewModelBase
  10. {
  11. private RelayCommand _randomizeCommand;
  12. private TimeEngine _timeEngine;
  13. private TimeFormat _timeFormat;
  14. private DateTime _time;
  15. private bool _isLoaded;
  16. private bool _multipleOfFive;
  17. public MainViewModel()
  18. {
  19. Configuration = new GlobalConfig();
  20. Configuration.Loaded += (sender, args) => Dispatcher.CurrentDispatcher.Invoke(
  21. new Action(() =>
  22. {
  23. _timeEngine = new TimeEngine();
  24. Time = _timeEngine.GenerateRandomTime(Configuration.Settings.MinutesMultipleOfFive);
  25. MultipleOfFive = Configuration.Settings.MinutesMultipleOfFive;
  26. IsSettingsLoaded = true;
  27. RaisePropertyChanged("TimeAsText");
  28. }));
  29. Configuration.LoadAsync();
  30. }
  31. //=================
  32. //== Свойства и т.д.
  33. //=================
  34. internal GlobalConfig Configuration { get; private set; }
  35. protected override void OnDispose()
  36. {
  37. Configuration.Save();
  38. }
  39. }
  40. }

GlobalConfig.cs

Листинг программы
  1. using System;
  2. using System.IO;
  3. using System.Threading;
  4. namespace Wpf_TimeRandomizer
  5. {
  6. public class GlobalConfig
  7. {
  8. public GlobalConfig()
  9. {
  10. }
  11. public AppFolders Folders { get; protected set; }
  12. public AppSettings Settings { get; protected set; }
  13. public event EventHandler Loaded;
  14. public virtual void Save()
  15. {
  16. AppSettings.Save(Settings, Path.Combine(Folders.MainData, Constants.SettingsFileName));
  17. }
  18. public virtual void LoadAsync()
  19. {
  20. ThreadPool.QueueUserWorkItem(unused =>
  21. {
  22. Folders = new AppFolders(Constants.AppName);
  23. Folders.CheckFolders();
  24. Settings = AppSettings.Load(Path.Combine(Folders.MainData, Constants.SettingsFileName)) ?? new AppSettings();
  25. OnLoaded();
  26. });
  27. }
  28. protected virtual void OnLoaded()
  29. {
  30. EventHandler handler = Loaded;
  31. if (handler != null)
  32. {
  33. handler(this, EventArgs.Empty);
  34. }
  35. }
  36. }
  37. }

MainViewModel.cs

Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace Wpf_TimeRandomizer.ViewModel
  6. {
  7. public class ViewModelLocator
  8. {
  9. private static MainViewModel _main;
  10. /// <summary>
  11. /// Initializes a new instance of the ViewModelLocator class.
  12. /// </summary>
  13. public ViewModelLocator()
  14. {
  15. CreateMain();
  16. }
  17. /// <summary>
  18. /// Gets the Main property.
  19. /// </summary>
  20. public static MainViewModel MainStatic
  21. {
  22. get
  23. {
  24. if (_main == null)
  25. {
  26. CreateMain();
  27. }
  28. return _main;
  29. }
  30. }
  31. /// <summary>
  32. /// Gets the Main property.
  33. /// </summary>
  34. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
  35. "CA1822:MarkMembersAsStatic",
  36. Justification = "This non-static member is needed for data binding purposes.")]
  37. public MainViewModel Main
  38. {
  39. get { return MainStatic; }
  40. }
  41. /// <summary>
  42. /// Provides a deterministic way to delete the Main property.
  43. /// </summary>
  44. public static void ClearMain()
  45. {
  46. _main.Dispose();
  47. _main = null;
  48. }
  49. /// <summary>
  50. /// Provides a deterministic way to create the Main property.
  51. /// </summary>
  52. public static void CreateMain()
  53. {
  54. if (_main == null)
  55. {
  56. _main = new MainViewModel();
  57. }
  58. }
  59. /// <summary>
  60. /// Cleans up all the resources.
  61. /// </summary>
  62. public static void Cleanup()
  63. {
  64. ClearMain();
  65. }
  66. }
  67. }
Суть такая: закрываю окно, вызывается обработчик события у окна Closing, из него вызывается ViewModelLocator.Cleanup(), он в свою очередь вызывает у MainViewModel метод Dispose, который вызывает Configuration.Save(), но настройки не успевают сохраниться и то есть файл настроек после закрытия окна, то его нет. Это не нужно думаю, но всё же выложу. Вот метод сохранения настроек.

Из класса AppSettings.cs

Листинг программы
  1. public static void Save(AppSettings settings, String fileName)
  2. {
  3. XmlSerializer xmlSerializer = new XmlSerializer(typeof(AppSettings));
  4. using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate))
  5. using (StreamWriter streamWriter = new StreamWriter(fs))
  6. {
  7. xmlSerializer.Serialize(streamWriter, settings);
  8. }
  9. }
Вообще суть в том, что я просто хочу сохранить настройки приложения, чтобы при следующем запуске их можно было загрузить. Тут используется паттерн MVVM. У меня на окошке 1 CheckBox и мне надо сохранять его состояние.
Тьфу, разобрался кажись, дело было в том, что при загрузке настроек вылетало исключение и файл настроек удалялся:
Листинг программы
  1. public static AppSettings Load(String fileName)
  2. {
  3. try
  4. {
  5. XmlSerializer xmlSerializer = new XmlSerializer(typeof(AppSettings));
  6. using (FileStream fs = new FileStream(fileName, FileMode.Open))
  7. using (StreamReader streamReader = new StreamReader(fs))
  8. {
  9. return (AppSettings)xmlSerializer.Deserialize(streamReader);
  10. }
  11. }
  12. catch
  13. {
  14. if (File.Exists(fileName))
  15. File.Delete(fileName);
  16. }
  17. return null;
  18. }
Короче сохранение надо сделать так, чтобы кажды раз новый файл создавался, а не дописывались данные в существующий, потому что в существующем почему-то появляется лишний закрывающий тег (>).
Решил проблему так, в методе Save класса AppSettings поменял параметр:
Листинг программы
  1. using (FileStream fs = new FileStream(fileName, FileMode.Create))
Было FileMode.CreateNew, стало FileMode.Create
Кстати, нормальный пример для тех, кто не любит выкладывать код и ждёт помощи, вот даже я тут как можно подробнее выложил, а проблема оказалась вообще в другом месте.

Решение задачи: «При закрытии формы "не успевают" сохраниться настройки»

textual
Листинг программы
  1. using (StreamWriter streamWriter = new StreamWriter( new FileStream(fileName, FileMode.Create) )

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы