我正在努力找出在WPF应用程序中实现用户设置的最佳策略。该应用程序将使用一个自定义控件的多个实例,该实例包含许多需要保留的属性。
我想出的一种策略是在自定义控件中内置一个类,该类包含要保留的属性(用户设置)。这些属性都与自定义控件相关,因此将它们放在那里是有意义的。此类具有双重目的:允许外部控件通过notify绑定到这些属性,以及将这些属性保存到磁盘。
[我拥有的是一个带有MainWindow的测试应用程序,并将自定义控件放置在xaml中,名为MyUserControlA。在自定义控件的构造函数中,从磁盘xml文件中读取设置类对象。然后在MainWindow构造函数中,定义绑定到settings类中的属性所需的数据上下文。当应用程序关闭时,会将设置对象写入磁盘。
但是,在读取设置文件时会遇到这种方法。此时,自定义实例的名称为空,因此它不知道要读取的文件名。
问题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();
}
}
}
}
}
WPF Application
类具有内置的应用程序范围Properties
,您可以看看Application.Properties。您可以在Application
启动时从xml文件读取所有设置,并将其存储在Properties
词典中
[另一种选择是使用Application settings,它们被保存在userSettings
文件中的app.config
部分下。您可以通过以下方式使用它们
Properties.Settings.Default.FirstUserSetting = "abc";
Properties.Settings.Default.Save();