У меня есть ToggleButton. Всякий раз, когда кто-то его проверяет, он устанавливает значение в реестр (regedit.exe), а если кто-то снимает флажок, он удаляет значение.
Теперь, когда я снова запускаю приложение, я хочу проверить, есть ли значение в реестре или нет, поэтому я устанавливаю ToggleButton Checked (если значение есть) или снимаю флажок (если его нет).
if (registry.GetValue("AppName") == null)
{
Toggle.IsChecked = false;
}
else
{
Toggle.IsChecked = true;
}
Проблема здесь в том, что после проверки и нахождения значения в реестре он установит для IsChecked значение true, и это вызовет «Проверено» и заставит его снова записать в реестр.
Это очень распространенная проблема, с которой люди сталкиваются при использовании привязки данных. Есть много способов решить эту проблему с помощью грязный и хакерский. Наиболее подходящий и чистый подход: Не манипулируйте элементами управления пользовательским интерфейсом из кода. Манипулируйте тем, к чему привязаны элементы управления ui, поэтому в вашем случае манипулируйте моделью просмотра. Также отключите привязку во время манипуляции ViewModel. По завершении включите привязку, и интерфейс обновится. Таким образом, флаг в вашей модели просмотра будет true, и когда пользовательский интерфейс привяжется к нему, он станет отмеченным. Это вызовет событие, что он проверен, но ваша модель просмотра уже синхронизирована.
Следовательно, ничего не будет. Это также полезно для того, чтобы во время загрузки и манипулирования моделью представления события не возникали повсюду и не замедляли загрузку. Другими словами, ваш код не должен щелкать элементы управления пользовательского интерфейса (control.Checked = true;). Это работа пользователя. Ваша работа - манипулировать моделью просмотра.





С оператором = вы назначаете логическое значение, поэтому оно запускает событие, если вы хотите проверить, является ли значение, попробуйте вместо этого сравнить (с оператором ==)
// dont do this
Toggle.IsChecked = registry.GetValue("AppName") == null ? false : true;
// do this instead
if (Toggle.IsChecked == true) // registry is apparently not null
{
// double check
if (registry.GetValue("AppName") != null)
{
// registry is not null
bRegistryIsEmpty = false;
}
}
else // registry is apparently null
{
// double check
if (registry.GetValue("AppName") == null)
{
// registry is null
bRegistryIsEmpty = true;
}
}
// or just do this
bRegistryIsEmpty = registry.GetValue("AppName") == null ? true : false;
Вы можете использовать логический флаг в своем обработчике событий, который не позволяет обработчику событий вызывать сам себя:
private bool _handle = true;
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
if (!_handle)
return;
bool isChecked = registry.GetValue("AppName") != null;
_handle = false; //prevent the event handler from being invoked
Toggle.IsChecked = isChecked;
_handle = true; //enable the event handler again
}
вы можете создать резервную копию частных полей со свойствами и установить значение поля в конструкторе или метод инициализации в вашей модели представления.