Существует способ настройки параметров reset с помощью Settings.Default.Reset()
Есть ли способ reset только одного свойства? Что-то вроде
Settings.Default.Properties["MyPropertyName"].Reset();
Существует способ настройки параметров reset с помощью Settings.Default.Reset()
Есть ли способ reset только одного свойства? Что-то вроде
Settings.Default.Properties["MyPropertyName"].Reset();
Найдено решение при чтении исходного кода .NET:
Settings.Default.PropertyValues["MyPropertyName"].SerializedValue = Settings.Default.Properties["MyPropertyName"].DefaultValue;
Settings.Default.PropertyValues["MyPropertyName"].Deserialized = false;
Вы можете использовать Settings.Default.Properties["MyProperty"].DefaultValue
для получения значения по умолчанию для свойства и установить для него значение свойства.
Это значение PropertyValue
, которое необходимо установить в комбинации Deserialized
(вопрос порядка):
public void ResetOneSetting(string propertyName)
{
SettingsPropertyValue propertyToReset = Settings.Default.PropertyValues.OfType<SettingsPropertyValue>().FirstOrDefault(p => p.Name == propertyName);
if (propertyToReset != null)
{
propertyToReset.PropertyValue = propertyToReset.Property.DefaultValue;
propertyToReset.Deserialized = false;
}
}
В моем случае (.NET Framework 4.6.1 с параметром System.Drawing.Color
качестве параметра) мне также пришлось переназначить значение в Settings.Default
, в противном случае изменение, похоже, было проигнорировано:
var propertyValue = Settings.Default.PropertyValues["myPropertyName"];
propertyValue.PropertyValue = propertyValue.Property.DefaultValue;
propertyValue.Deserialized = false;
Settings.Default["myPropertyName"] = propertyValue.PropertyValue;
Я использую следующий код для сброса настроек в моей программе. Он использует преимущества отражения и позволяет вам передавать свойство напрямую, а не выписывать имя свойства вручную. Он может использоваться как ResetToDefaultValue(TestSettings.Default, x => x.TextFieldStuff);
Преимущество этого состоит в том, что не все ваши настройки находятся в Settings
но некоторые могут храниться в разных файлах настроек.
//Way to use
//ResetToDefaultValue(TestSettings.Default, x => x.TextFieldStuff);
private static void ResetToDefaultValue<T1, T2>(T1 settings, Expression<Func<T1, T2>> property, bool saveOnReset = true)
{
if (IsSameOrSubclass(typeof(ApplicationSettingsBase), settings.GetType()))
{
ApplicationSettingsBase s = settings as ApplicationSettingsBase;
if (s != null)
{
MemberInfo member = GetMemberInfo(property);
if (!s.PropertyValues[member.Name].UsingDefaultValue)
{
s.PropertyValues[member.Name].PropertyValue = s.PropertyValues[member.Name].Property.DefaultValue;
s.PropertyValues[member.Name].Deserialized = false;
s[member.Name] = s.PropertyValues[member.Name].PropertyValue; //Triggers the property changed
if (saveOnReset)
{
s.Save();
}
}
}
}
}
//Way to use
//GetMemberInfo((TestSettings testSettings) => testSettings.TextFieldStuff);
private static MemberInfo GetMemberInfo<T1, T2>(Expression<Func<T1, T2>> expression)
{
if (IsSameOrSubclass(typeof(MemberExpression), expression.Body.GetType()))
{
MemberExpression member = (MemberExpression)expression.Body;
return member.Member;
}
throw new ArgumentException(@"Expression is not a member access", nameof(expression));
}
private static bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}
Или, если вы используете С# 7.1 или выше, вы можете использовать сопоставление функций.
//Way to use
//ResetToDefaultValue(TestSettings.Default, x => x.TextFieldStuff);
private static void ResetToDefaultValue<T1, T2>(T1 settings, Expression<Func<T1, T2>> property, bool saveOnReset = true)
{
//Requires C# >= 7.1
if (settings is ApplicationSettingsBase s)
{
MemberInfo member = GetMemberInfo(property);
if (!s.PropertyValues[member.Name].UsingDefaultValue)
{
s.PropertyValues[member.Name].PropertyValue = s.PropertyValues[member.Name].Property.DefaultValue;
s.PropertyValues[member.Name].Deserialized = false;
s[member.Name] = s.PropertyValues[member.Name].PropertyValue;
if (saveOnReset)
{
s.Save();
}
}
}
}
//Way to use
//GetMemberInfo((TestSettings testSettings) => testSettings.TextFieldStuff);
private static MemberInfo GetMemberInfo<T1, T2>(Expression<Func<T1, T2>> expression)
{
//Requires C# >= 7.0
if (expression.Body is MemberExpression member)
{
return member.Member;
}
throw new ArgumentException(@"Expression is not a member access", nameof(expression));
}
Пока я проверял ответы @dalleria и @nikita, я столкнулся с проблемой, PropertyValue (SettingsPropertyValue) по умолчанию не устанавливался, когда я пытался получить глубокую копию DefaultValue (SettingsProperty) или PropertyValue (SettingsPropertyValue) или любого другого такого же типизированного значения.
Итак, вот моя короткая реализация функции глубокого копирования, которая является частью класса, поэтому я прошу прощения за то, что не реорганизовал ее в метод расширения или инструмента.
private SettingsPropertyValue settingsPropertyValue; // (ex. Settings.Default.PropertyValues["anyPropertyName"])
private SettingsProperty settingsProperty
=> settingsPropertyValue.Property;
/// <summary>
/// Create a deep copy of <paramref name="value"/>.
/// </summary>
/// <param name="value">
/// Should be a deserialized value (ex. <see cref="SettingsPropertyValue.PropertyValue"/>)
/// or a serialized value (ex. <see cref="SettingsProperty.DefaultValue"/>).
/// </param>
/// <param name="isDeserialized">Indicates whether <paramref name="value"/> is deserialized or serialized.</param>
private PropertyType copyValue<PropertyType>(object value, bool isDeserialized)
{
var temporaryPropertyValue = settingsPropertyValue.PropertyValue;
settingsPropertyValue.PropertyValue = value;
if (isDeserialized)
// We have to reassign, otherwise PropertyValue/SerializedValue of SettingsPropertyValue may be defaulted
settingsPropertyValue.SerializedValue = settingsPropertyValue.SerializedValue;
settingsPropertyValue.Deserialized = false;
var propertyValue = (PropertyType)settingsPropertyValue.PropertyValue;
settingsPropertyValue.PropertyValue = temporaryPropertyValue;
return propertyValue;
}
Затем можно сбросить одно свойство экземпляра ApplicationSettings/SettingsBase с помощью следующих строк:
SettingsBase settings; // (ex. Settings.Default)
public void SetOriginalFromDefault()
{
object defaultValue = settingsProperty.DefaultValue;
defaultValue = copyValue(defaultValue, false);
// We want to set the new value. It also triggers the INotifyPropertyChanged of settings, if the instance is from type ApplicationSettings
settings[settingsProperty.Name] = defaultValue;
}