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

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

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

MainWindow.xaml.cs

using System.Windows;
using Wpf_TimeRandomizer.ViewModel;
 
namespace Wpf_TimeRandomizer
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Closing += (s, e) => ViewModelLocator.Cleanup();
        }
    }
}

MainViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using Wpf_TimeRandomizer.Model;
 
namespace Wpf_TimeRandomizer.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private RelayCommand _randomizeCommand;
        private TimeEngine _timeEngine;
        private TimeFormat _timeFormat;
        private DateTime _time;
        private bool _isLoaded;
        private bool _multipleOfFive;
 
        public MainViewModel()
        {
            Configuration = new GlobalConfig();
            Configuration.Loaded += (sender, args) => Dispatcher.CurrentDispatcher.Invoke(
                new Action(() =>
                {
                    _timeEngine = new TimeEngine();
                    Time = _timeEngine.GenerateRandomTime(Configuration.Settings.MinutesMultipleOfFive);
                    MultipleOfFive = Configuration.Settings.MinutesMultipleOfFive;
                    IsSettingsLoaded = true;
                    RaisePropertyChanged("TimeAsText");
                }));
            Configuration.LoadAsync();
        }
 
        //=================
        //== Свойства и т.д.
        //=================
 
        internal GlobalConfig Configuration { get; private set; }
 
        protected override void OnDispose()
        {
            Configuration.Save();
        }
    }
}

GlobalConfig.cs

using System;
using System.IO;
using System.Threading;
 
namespace Wpf_TimeRandomizer
{
    public class GlobalConfig
    {
        public GlobalConfig()
        {
        }
 
        public AppFolders Folders { get; protected set; }
 
        public AppSettings Settings { get; protected set; }
 
        public event EventHandler Loaded;
 
        public virtual void Save()
        {
             AppSettings.Save(Settings, Path.Combine(Folders.MainData, Constants.SettingsFileName));
        }
 
        public virtual void LoadAsync()
        {
            ThreadPool.QueueUserWorkItem(unused =>
                {
                    Folders = new AppFolders(Constants.AppName);
                    Folders.CheckFolders();
                    Settings = AppSettings.Load(Path.Combine(Folders.MainData, Constants.SettingsFileName)) ?? new AppSettings();
                    OnLoaded();
                });
        }
 
        protected virtual void OnLoaded()
        {
            EventHandler handler = Loaded;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
}

MainViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Wpf_TimeRandomizer.ViewModel
{
    public class ViewModelLocator
    {
        private static MainViewModel _main;
 
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            CreateMain();
        }
 
        /// <summary>
        /// Gets the Main property.
        /// </summary>
        public static MainViewModel MainStatic
        {
            get
            {
                if (_main == null)
                {
                    CreateMain();
                }
 
                return _main;
            }
        }
 
        /// <summary>
        /// Gets the Main property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public MainViewModel Main
        {
            get { return MainStatic; }
        }
 
        /// <summary>
        /// Provides a deterministic way to delete the Main property.
        /// </summary>
        public static void ClearMain()
        {
            _main.Dispose();
            _main = null;
        }
 
        /// <summary>
        /// Provides a deterministic way to create the Main property.
        /// </summary>
        public static void CreateMain()
        {
            if (_main == null)
            {
                _main = new MainViewModel();
            }
        }
 
        /// <summary>
        /// Cleans up all the resources.
        /// </summary>
        public static void Cleanup()
        {
            ClearMain();
        }
    }
}
Суть такая: закрываю окно, вызывается обработчик события у окна Closing, из него вызывается ViewModelLocator.Cleanup(), он в свою очередь вызывает у MainViewModel метод Dispose, который вызывает Configuration.Save(), но настройки не успевают сохраниться и то есть файл настроек после закрытия окна, то его нет. Это не нужно думаю, но всё же выложу. Вот метод сохранения настроек.

Из класса AppSettings.cs

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

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

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

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


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

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

9   голосов , оценка 4 из 5
Похожие ответы