/// <summary> /// Обновляет VMs по найденным болезням /// </summary> /// <param name="results"></param> private void MakeVms(ObservableCollection <IcdDisease> results) { var doctor = AuthorityController.CurrentDoctor; Func <IcdDisease, bool> diseaseClause = d => true; if (IcdTopLevelOnly) { // без уточненных болезней diseaseClause = d => !d.IsSubdivision; } Func <IcdBlock, bool> blockClause = b => true; if (doctor != null && doctor.Speciality != null) { // блоки для специальности доктора blockClause = b => doctor.Speciality.IcdBlocks.Contains(b); } Dictionary <IcdChapter, Dictionary <IcdBlock, IEnumerable <IcdDisease> > > dict = (from d in results group d by d.IcdBlock.IcdChapter into gr let blocks = (from be in gr group be by be.IcdBlock into grr where blockClause(grr.Key) select new { Block = grr.Key, Diseases = grr.Where(diseaseClause) }).ToDictionary(x => x.Block, x => x.Diseases) where blocks.Count > 0 // без пустых классов select new { Chapter = gr.Key, Blocks = blocks }).ToDictionary(x => x.Chapter, x => x.Blocks); // для каждого класса, блока и болезни ищем существующую VM или создаем // разворачиваем // синхронизируем с детьми уровня выше Func <DiagnosisViewModel, IIcdEntity> compareKey = (vm) => vm.Icd; var inMaking = true; var chVms = dict.Keys.Select(ch => { var chVm = Chapters.Where(i => i.Icd as IcdChapter == ch).FirstOrDefault(); if (chVm == null) { chVm = new DiagnosisViewModel(ch); chVm.PropertyChanged += (s, e) => { // сохраняем выбор пользователя if (e.PropertyName == "IsExpanded" && !inMaking) { chVm.UserExpaneded = chVm.IsExpanded; } }; } var bVms = dict[ch].Keys.Select(b => { var bVm = chVm.Children.Where(i => i.Icd as IcdBlock == b).FirstOrDefault(); if (bVm == null) { bVm = new DiagnosisViewModel(b); bVm.PropertyChanged += (s, e) => { // сохраняем выбор пользователя if (e.PropertyName == "IsExpanded" && !inMaking) { bVm.UserExpaneded = bVm.IsExpanded; } }; } var dVms = dict[ch][b].Select(d => { var dVm = bVm.Children.Where(i => i.Icd as IcdDisease == d) .FirstOrDefault() ?? new DiagnosisViewModel(d); return(dVm); }).ToList(); // блоки остаются в состоянии, выбранном пользователем bVm.IsExpanded = (bVm.UserExpaneded ?? false) ? true : // был раскрыт пользователем (TypedEnough() && (bVm.UserExpaneded ?? true)); // или запрос достаточно точный и блок не был свернут bVm.Children.SyncWith(dVms); return(bVm); }).ToList(); // глава раскрыта, если не была свернута пользователем chVm.IsExpanded = chVm.UserExpaneded ?? true; chVm.Children.SyncWith(bVms); return(chVm); }).ToList(); inMaking = false; // всегда раскрыта глава и блок с выбранной болезнью (hieratchicalbase) // TODO длинный запрос — vm удаляются, сохранять UserExpaneded для каждой Chapters.SyncWith(chVms); }