From caee9fafd5e26dae993c76f35acd343ba2e7b9f7 Mon Sep 17 00:00:00 2001 From: Alek-ban Date: Sat, 20 Jun 2026 11:58:14 +0300 Subject: [PATCH] fix: possible edge case (or kind of) sample calibration view model move brand combobox editing on database changing to uI thread --- .../SampleCalibrationViewModel.cs | 84 ++++++++++--------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/GSS2/ViewModels/AmineContent/SampleCalibrationViewModel.cs b/GSS2/ViewModels/AmineContent/SampleCalibrationViewModel.cs index c3fbdf6..01826cd 100644 --- a/GSS2/ViewModels/AmineContent/SampleCalibrationViewModel.cs +++ b/GSS2/ViewModels/AmineContent/SampleCalibrationViewModel.cs @@ -232,50 +232,56 @@ public partial class SampleCalibrationViewModel : ViewModelBase // Подписываемся на изменения базы данных для отслеживания изменений списка марок _context.ChangeTracker.StateChanged += (_, ea) => { - // Если запись не интересует нас, то ничего не делаем - if (ea.Entry.Entity is not BrandRecord brandRecord) - return; + // Обновляем данные в интерфейсе + // Dispatcher.UIThread.Invoke нужен потому-что этот метод может (и скорее всего будет) вызван в другом потоке, + // а изменения данных в интерфейсе могут быть вызваны только из потока в котором интерфейс был создан + _ = Dispatcher.UIThread.InvokeAsync(() => + { + // Если запись не интересует нас, то ничего не делаем + if (ea.Entry.Entity is not BrandRecord brandRecord) + return; - // Если запись добавлена - if (ea.NewState is EntityState.Added) - { - // Добавляем запись - BrandComboBoxItems.Add(new BrandComboBoxItemViewModel(brandRecord.Id, brandRecord.BrandName, brandRecord.MixtureName)); - } - // Если запись удалена - else if (ea.NewState is EntityState.Deleted) - { - // Ищем удалённую запись в выпадающем списке марок - var deletedComboBoxItem = BrandComboBoxItems.FirstOrDefault(r => r.Id == brandRecord.Id); - // Если запись не найдена в выпадающем списке марок, то логгируем как ошибку - if (deletedComboBoxItem is null) + // Если запись добавлена + if (ea.NewState is EntityState.Added) { - _logger.LogError("Не удалось найти элемент с Id({}) в списке {}", brandRecord.Id, nameof(BrandComboBoxItems)); - return; + // Добавляем запись + BrandComboBoxItems.Add(new BrandComboBoxItemViewModel(brandRecord.Id, brandRecord.BrandName, brandRecord.MixtureName)); } - // Берём индекс удалённого элемента в выпадающем списке марок - var deletedComboBoxIndex = BrandComboBoxItems.IndexOf(deletedComboBoxItem); - // Если текущий индекс равен удаляемому, то устанавливаем, что элемент не выбран - if (BrandComboBoxSelectedIndex == deletedComboBoxIndex) - BrandComboBoxSelectedIndex = -1; - // Удаляем элемент из выпадающего списка марок - BrandComboBoxItems.RemoveAt(deletedComboBoxIndex); - } - // Если запись изменилась - else if (ea.NewState is EntityState.Modified) - { - // Ищем изменённую запись в выпадающем списке марок - var editedComboBoxItem = BrandComboBoxItems.FirstOrDefault(r => r.Id == brandRecord.Id); - // Если запись не найдена в выпадающем списке марок, то логгируем как ошибку - if (editedComboBoxItem is null) + // Если запись удалена + else if (ea.NewState is EntityState.Deleted) { - _logger.LogError("Не удалось найти элемент с Id({}) в списке {}", brandRecord.Id, nameof(BrandComboBoxItems)); - return; + // Ищем удалённую запись в выпадающем списке марок + var deletedComboBoxItem = BrandComboBoxItems.FirstOrDefault(r => r.Id == brandRecord.Id); + // Если запись не найдена в выпадающем списке марок, то логгируем как ошибку + if (deletedComboBoxItem is null) + { + _logger.LogError("Не удалось найти элемент с Id({}) в списке {}", brandRecord.Id, nameof(BrandComboBoxItems)); + return; + } + // Берём индекс удалённого элемента в выпадающем списке марок + var deletedComboBoxIndex = BrandComboBoxItems.IndexOf(deletedComboBoxItem); + // Если текущий индекс равен удаляемому, то устанавливаем, что элемент не выбран + if (BrandComboBoxSelectedIndex == deletedComboBoxIndex) + BrandComboBoxSelectedIndex = -1; + // Удаляем элемент из выпадающего списка марок + BrandComboBoxItems.RemoveAt(deletedComboBoxIndex); } - // Обновляем элемент из выпадающего списка марок - editedComboBoxItem.BrandName = brandRecord.BrandName; - editedComboBoxItem.MixtureName = brandRecord.MixtureName; - } + // Если запись изменилась + else if (ea.NewState is EntityState.Modified) + { + // Ищем изменённую запись в выпадающем списке марок + var editedComboBoxItem = BrandComboBoxItems.FirstOrDefault(r => r.Id == brandRecord.Id); + // Если запись не найдена в выпадающем списке марок, то логгируем как ошибку + if (editedComboBoxItem is null) + { + _logger.LogError("Не удалось найти элемент с Id({}) в списке {}", brandRecord.Id, nameof(BrandComboBoxItems)); + return; + } + // Обновляем элемент из выпадающего списка марок + editedComboBoxItem.BrandName = brandRecord.BrandName; + editedComboBoxItem.MixtureName = brandRecord.MixtureName; + } + }); }; // Подписываемся на изменения свойств для обновления CanScroll