Gre*_*reg 69 .net c# wpf settings
您建议在WPF窗口(桌面)应用程序中保留用户设置的方法是什么?请注意,该想法是用户可以在运行时更改其设置,然后可以关闭应用程序,然后在稍后启动应用程序时,应用程序将使用当前设置.有效地,它看起来好像应用程序设置不会改变.
Q1 - 数据库还是其他方法?我确实有一个我将使用的sqlite数据库,因此使用数据库中的表将与任何方法一样好吗?
Q2 - 如果数据库:什么数据库表设计?与一个可能有不同的数据类型的列一个表(例如string,long,DateTime等),或者只是一个用于在您拥有序列化和反序列化值,该值的字符串表?我想第一个会更容易,如果设置不多,开销就不多了?
Q3 - 可以使用应用程序设置吗?如果是这样,是否需要在此处启用持久性的特殊任务?在这种情况下,在应用程序设置设计器中使用"默认"值会发生什么?默认会覆盖运行应用程序之间保存的所有设置吗?(或者你需要不使用默认值)
Gle*_*den 12
您可以Strings在XML中存储XML格式的设置信息Settings.Default.创建一些类来存储配置数据并确保它们是[Serializable].然后,使用以下帮助程序,您可以将这些对象的实例 - 或List<T>(或数组T[]等)序列化为String.将这些不同的字符串中的每一个存储Settings.Default在WPF应用程序的各自插槽中Settings.
要在下次应用程序启动时恢复对象,请读取Settings感兴趣的字符串和Deserialize预期的类型T(此时必须明确指定为类型参数Deserialize<T>).
public static String Serialize<T>(T t)
{
using (StringWriter sw = new StringWriter())
using (XmlWriter xw = XmlWriter.Create(sw))
{
new XmlSerializer(typeof(T)).Serialize(xw, t);
return sw.GetStringBuilder().ToString();
}
}
public static T Deserialize<T>(String s_xml)
{
using (XmlReader xw = XmlReader.Create(new StringReader(s_xml)))
return (T)new XmlSerializer(typeof(T)).Deserialize(xw);
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*Mat 10
我也更喜欢序列化文件.XML文件几乎适合所有要求.您可以使用ApplicationSettings内置版本,但这些内容有一些限制和定义但(对我来说)存储的非常奇怪的行为.我经常使用它们并且它们起作用.但是如果你想完全控制它们存储的方式和位置,我会使用另一种方法.
MySettings好处:
缺点: - 您必须考虑存储设置文件的位置.(但你可以使用你的安装文件夹)
这是一个简单的例子(未经测试) -
public class MySettings
{
public string Setting1 { get; set; }
public List<string> Setting2 { get; set; }
public void Save(string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
xmls.Serialize(sw, this);
}
}
public MySettings Read(string filename)
{
using (StreamReader sw = new StreamReader(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
return xmls.Deserialize(sw) as MySettings;
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它.只需检查用户设置是否存在,就可以加载默认值或使用用户设置覆盖默认值:
public class MyApplicationLogic
{
public const string UserSettingsFilename = "settings.xml";
public string _DefaultSettingspath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\" + UserSettingsFilename;
public string _UserSettingsPath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\UserSettings\\" +
UserSettingsFilename;
public MyApplicationLogic()
{
// if default settings exist
if (File.Exists(_UserSettingsPath))
this.Settings = Settings.Read(_UserSettingsPath);
else
this.Settings = Settings.Read(_DefaultSettingspath);
}
public MySettings Settings { get; private set; }
public void SaveUserSettings()
{
Settings.Save(_UserSettingsPath);
}
}
Run Code Online (Sandbox Code Playgroud)
也许有人会受到这种方法的启发.这就是我多年来一直这样做的原因,我很满意.
长期运行这个问题的最典型方法是:隔离存储.
将控件状态序列化为XML或其他格式(如果使用WPF保存依赖项属性,则特别容易),然后将文件保存到用户的独立存储中.
如果您确实想要进入应用程序设置路线,我自己尝试了类似的东西......虽然下面的方法可以很容易地适应使用隔离存储:
class SettingsManager
{
public static void LoadSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
EnsureProperties(sender, savedElements);
foreach (FrameworkElement element in savedElements.Keys)
{
try
{
element.SetValue(savedElements[element], Properties.Settings.Default[sender.Name + "." + element.Name]);
}
catch (Exception ex) { }
}
}
public static void SaveSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
EnsureProperties(sender, savedElements);
foreach (FrameworkElement element in savedElements.Keys)
{
Properties.Settings.Default[sender.Name + "." + element.Name] = element.GetValue(savedElements[element]);
}
Properties.Settings.Default.Save();
}
public static void EnsureProperties(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
foreach (FrameworkElement element in savedElements.Keys)
{
bool hasProperty =
Properties.Settings.Default.Properties[sender.Name + "." + element.Name] != null;
if (!hasProperty)
{
SettingsAttributeDictionary attributes = new SettingsAttributeDictionary();
UserScopedSettingAttribute attribute = new UserScopedSettingAttribute();
attributes.Add(attribute.GetType(), attribute);
SettingsProperty property = new SettingsProperty(sender.Name + "." + element.Name,
savedElements[element].DefaultMetadata.DefaultValue.GetType(), Properties.Settings.Default.Providers["LocalFileSettingsProvider"], false, null, SettingsSerializeAs.String, attributes, true, true);
Properties.Settings.Default.Properties.Add(property);
}
}
Properties.Settings.Default.Reload();
}
}
Run Code Online (Sandbox Code Playgroud)
.....和....
Dictionary<FrameworkElement, DependencyProperty> savedElements = new Dictionary<FrameworkElement, DependencyProperty>();
public Window_Load(object sender, EventArgs e) {
savedElements.Add(firstNameText, TextBox.TextProperty);
savedElements.Add(lastNameText, TextBox.TextProperty);
SettingsManager.LoadSettings(this, savedElements);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
SettingsManager.SaveSettings(this, savedElements);
}
Run Code Online (Sandbox Code Playgroud)
除了数据库,您还可以使用以下选项来保存用户相关设置
下注册 HKEY_CURRENT_USER
在文件AppData夹中的文件中
Settings在 WPF 中使用文件并将其范围设置为用户