Постоянные пользовательские настройки с привязкой данных для пользовательских элементов управления WPF - PullRequest
0 голосов
/ 26 октября 2019

Я изо всех сил пытаюсь найти лучшую стратегию для реализации пользовательских настроек в моем приложении WPF. Приложение будет использовать несколько экземпляров пользовательского элемента управления, содержащего множество свойств, которые необходимо сохранить.

Одна из стратегий, которую я придумала, состоит в том, чтобы встроить в пользовательский элемент управления класс, содержащий свойства (пользовательские настройки). ) Я хочу упорствовать. Все эти свойства связаны с пользовательским элементом управления, поэтому имеет смысл поместить их туда. Этот класс имеет двойное назначение: разрешить внешним элементам управления связываться с этими свойствами с помощью уведомлений, а также сохранять эти свойства на диск.

У меня есть тестовое приложение с MainWindow с пользовательским элементом управления, помещенным в xaml и названным MyUserControlA. В конструкторе пользовательского элемента управления объект класса настроек считывается из файла xml диска. Затем в конструкторе MainWindow определяется текст данных для всего, что необходимо связать со свойствами в классе настроек. А когда приложение закрывается, объект настроек записывается на диск.

Однако при таком подходе возникает одна проблема при чтении файла настроек. На данный момент имя пользовательского экземпляра пустое, поэтому он не знает имя файла для чтения.

Вопрос 1. Если это жизнеспособный подход, как мы можем получить имя пользовательскогоуправлять экземпляром, чтобы мы могли получить имя файла?

Вопрос 2: Есть ли лучший подход, чем тот, который у меня здесь?

Спасибо.

MainWindow

namespace UserSettings
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MyTextBox.DataContext = MyUserControlA.MySettings;
        }
    }
}

MyUserControl

namespace UserSettings
{
    /// <summary>
    /// Interaction logic for MyUserControl.xaml
    /// </summary>
    public partial class MyUserControl : UserControl
    {
        public Settings MySettings;

        public MyUserControl()
        {
            InitializeComponent();

            MySettings = ReadSettings();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Window window = Window.GetWindow(this);
            window.Closing += Window_Closing;
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            WriteSettings();
        }

        private Settings ReadSettings()
        {
            Settings returnSettings = null;

            var serializer = new XmlSerializer(typeof(Settings));

            if (File.Exists(Name + "Settings.xml")) // The Name is blank!
            {
                var fs = new FileStream(Name + "Settings.xml", FileMode.Open);  
                returnSettings = (Settings)serializer.Deserialize(fs);
                fs.Close();
            }

            if (returnSettings == null)
                returnSettings = new Settings();

            return returnSettings;
        }


        private void WriteSettings()
        {
            var serializer = new XmlSerializer(typeof(Settings));
            var writer = new StreamWriter(Name + "Settings.xml");
            serializer.Serialize(writer, MySettings);
            writer.Close();
        }
    }

    public partial class MyUserControl
    {

        [Serializable()]
        public class Settings : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
            protected void SetPropertyField<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
            {
                if (!EqualityComparer<T>.Default.Equals(field, newValue))
                {
                    field = newValue; OnPropertyChanged(propertyName);
                }
            }

            private string _MyStringProperty; public string MyStringProperty
            {
                get
                {
                    return _MyStringProperty;
                }
                set
                {
                    _MyStringProperty = value; OnPropertyChanged();
                }
            }
        }
    }
}
...