/// <summary> /// Формирование дочерних объектов сразу по нескольким узлам /// </summary> /// <param name="tempList">Список объектов, по которым прогружаем дочерние</param> /// <param name="descriptor">Описатель дерева</param> public void LoadDynamicChildren(IEnumerable <FreeHierarchyTreeItem> tempList) { #if DEBUG var sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif var comparer = new FreeHierarchyTreeItemComparer(); //Это стандартные деревья foreach (var item in tempList) { if (item.IncludeObjectChildren) { if (Tree_ID <= 0) { item.IsFreeHierLoadedInitializet = true; } var brunch = item.AddStandartChildren(false, true, false, false); if (brunch != null) { item.Children.AddRange(brunch.OrderBy(b => b, comparer)); } } item.IsLocalChildrenInitializet = true; if (Tree_ID <= 0) { item.IsChildrenInitializet = true; } } #if DEBUG sw.Stop(); Console.WriteLine("LoadDynamicChildren: стандартные деревья {0} млс", sw.ElapsedMilliseconds); sw.Restart(); #endif if (Tree_ID <= 0) { return; } //Пока работает кроме ФИАС var parendIds = tempList .Where(tl => !tl.IsFreeHierLoadedInitializet) .Select(tl => tl.FreeHierItem_ID) .ToList(); var branches = FreeHierarchyService.GetBranches(Manager.User.User_ID, Tree_ID.GetValueOrDefault(), parendIds, false); if (branches == null) { return; } var itemsForPrepare = new List <TFreeHierarchyTreeItem>(); foreach (var branch in branches) { if (branch.Value == null) { continue; } itemsForPrepare.AddRange(branch.Value); } #if DEBUG sw.Stop(); Console.WriteLine("LoadDynamicChildren: GetBranches {0} млс", sw.ElapsedMilliseconds); sw.Restart(); #endif FreeHierarchyTreePreparer.PrepareGlobalDictionaries(itemsForPrepare); foreach (var item in tempList) { if (item.IsFreeHierLoadedInitializet) { continue; } List <TFreeHierarchyTreeItem> children; if (branches.TryGetValue(item.FreeHierItem_ID, out children) && children != null) { var brunch = FreeHierarchyTreePreparer.BuildBranch(item, children, this, false, null, false); if (brunch != null) { item.Children.AddRange(brunch.OrderBy(b => b, comparer)); } } item.IsChildrenInitializet = true; } #if DEBUG sw.Stop(); Console.WriteLine("LoadDynamicChildren: PrepareGlobalDictionaries and BuildBranch {0} млс", sw.ElapsedMilliseconds); #endif }
/// <summary> /// Выделяем дочерние объекты из построенного на сервере пути /// </summary> /// <param name="items">объекты по которыми проходимся и выделяем</param> /// <param name="objectsFromSQL">объекты с путями, которые нужно выделить</param> public void SelectFromSets(IEnumerable <FreeHierarchyTreeItem> items, Dictionary <string, List <List <ID_TypeHierarchy> > > objectsFromSQL, bool isExpandFirst = false) { if (items == null || objectsFromSQL == null || objectsFromSQL.Count == 0) { return; } //Объекты, которые нужно предварительно подготовить, прежде чем выделять там дочерние var itemsForPrepare = new List <FreeHierarchyTreeItem>(); //Объекты у которых меняются чек боксы о том что там выделены дочерние var itemsByLevForUpdateChekbox = new Dictionary <int, HashSet <int> >(); //Объекты у которых нужно уведомить визуальку что изменились статусы var selectedItems = new List <FreeHierarchyTreeItem>(); var firstPath = new List <ID_TypeHierarchy>(); firstPath.AddRange(objectsFromSQL.First().Value.First()); if (!_treeItemsSyncLock.TryEnterWriteLock(_maxLockWait)) { return; } #if DEBUG var sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif try { //Сначала выделяем доступные объекты var fromSets = SelectRecursiveFromSets(items, objectsFromSQL, itemsForPrepare, selectedItems, itemsByLevForUpdateChekbox); objectsFromSQL = fromSets .GroupBy(sp => { if (sp == null || sp.Count == 0) { return(string.Empty); } return(sp.Last().ToRootPath); }) .Where(g => !string.IsNullOrEmpty(g.Key)) .ToDictionary(k => k.Key, v => v.ToList()); #if DEBUG sw.Stop(); Console.WriteLine("FreeHierarchyTreeDescriptor, Select {0} млс", sw.ElapsedMilliseconds); sw.Restart(); #endif //Подготавливаем недоступные объекты и потом выделяем //Рекурсивная подготовка дочерних объектов do { //Подгружаем внутренние словари для определения количества FreeHierarchyTreePreparer.PrepareGlobalDictionaries(itemsForPrepare, EnumFreeHierarchyTreePrepareMode.All); //Формируем дочерние узлы у прогруженных объектов, для того, чтобы идти дальше вниз по дереву LoadDynamicChildren(itemsForPrepare); var newitems = itemsForPrepare.ToList(); itemsForPrepare.Clear(); fromSets = SelectRecursiveFromSets(newitems, objectsFromSQL, itemsForPrepare, selectedItems, itemsByLevForUpdateChekbox); //Теперь выделяем подготовленные объекты objectsFromSQL = fromSets .Where(sp => sp.Count > 0) .GroupBy(sp => sp.Last().ToRootPath) .ToDictionary(k => k.Key, v => v.ToList()); } while (itemsForPrepare.Count > 0); //Идем дальше вниз по дереву, пока не останется объектов для выделения, либо пока не кончится дерево #if DEBUG sw.Stop(); Console.WriteLine("FreeHierarchyTreeDescriptor, PrepareParentsAndSelectChildrenAsync {0} млс", sw.ElapsedMilliseconds); #endif } catch (Exception ex) { Manager.UI.ShowMessage(ex.ToString()); } finally { _treeItemsSyncLock.ExitWriteLock(); } //Уведомляем визуалку что изменились состояния объектов на дереве FreeHierarchyTree.InvokeAsync(() => { //Проставляем чек боксы на родителя у которых выделены дочерние ProcessParentCheckboxes(itemsByLevForUpdateChekbox); //Уведомляем визуалку что изменились статусы выделения RaiseSelectedItemsChanged(selectedItems); FreeHierarchyTree.DescOnSelectedChanged(); if (isExpandFirst) { var path = new ConcurrentStack <ID_TypeHierarchy>(firstPath); FreeHierarchyTree.ExpandFromSQL(FreeHierarchyTree.NodeCollection, path, false); } }, DispatcherPriority.DataBind); }
public static IDictionary <int, FreeHierarchyTreeItem> GetTree(FreeHierarchyTreeDescriptor descriptor, out bool isFirstLoaded, bool isHideTi = false, HashSet <long> selectedNodes = null, bool isFullReload = false, HashSet <int> singreRootFreeHierItemIds = null) { isFirstLoaded = false; //Признак администратора bool isUserAdmin = Manager.User.IsAdmin; #if DEBUG var sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif #region это стандартные деревья их не загружаем switch (descriptor.Tree_ID) { //case TreeTypeStandartPS: case TreeTypeStandartTIFormula: case TreeTypeStandartDistributingArrangementAndBusSystem: //if (isFullReload) //{ // descriptor.UpdateIncludedObjectChildrenAsync(Manager.User.User_ID); //} return(GenerateStandartTreePS(descriptor, isHideTi)); case TreeTypeStandartSections: case TreeTypeStandartSectionsNSI: return(GenerateStandartTreeSections(descriptor)); case TreeTypeStandartBySupplyPS: return(GenerateStandartTreeBySupplyPS(descriptor, isHideTi)); case TreeTypeStandartGroupTP: return(JuridicalPersonTree.GenerateJuridicalPersonTree(descriptor, true, false)); case TreeTypeStandartJuridicalPerson: return(JuridicalPersonTree.GenerateJuridicalPersonTree(descriptor, false, true)); case TreeTypeStandart_Dict_OPCUAServers: return(GenerateStandartTree_Dict_OPCUAServers(descriptor)); case TreeTypeStandart_Dict_FIAS: return(GenerateStandartTree_FIAS(false, descriptor)); case TreeTypeStandart_Dict_FIASToHierarchy: return(GenerateStandartTree_FIAS(true, descriptor)); case TreeExplXmlExportConfigs: return(GenerateExplXmlExportConfigsTree(descriptor)); case TreeExplXmlBalance63: return(GenerateBalance63Tree(descriptor)); case TreeOldTelescope: return(GenerateOldTelescopeTree(descriptor)); } #endregion var result = new ConcurrentDictionary <int, FreeHierarchyTreeItem>(); List <TFreeHierarchyTreeItem> tempList = null; try { int?parenId = null; if (singreRootFreeHierItemIds != null) { parenId = singreRootFreeHierItemIds.FirstOrDefault(); } tempList = FreeHierarchyTreeDictionary.GetBranch(Manager.User.User_ID, descriptor.Tree_ID.GetValueOrDefault(), parenId, isFullReload, onError: Manager.UI.ShowMessage); } catch (Exception ex) { Manager.UI.ShowMessage(ex.Message); } #if DEBUG sw.Stop(); Console.WriteLine("Запрос дерева в БД {0} млс", sw.ElapsedMilliseconds); sw.Restart(); #endif if (tempList == null) { return(result); } FreeHierarchyTreePreparer.PrepareGlobalDictionaries(tempList); if (descriptor != null) { descriptor.Tree = result; } foreach (var newItem in FreeHierarchyTreePreparer.BuildBranch(null, tempList, descriptor, isHideTi, selectedNodes)) { result.TryAdd(newItem.FreeHierItem_ID, newItem); } //if ((uspdList!=null&&(uspdList.Count>0))) //{ // ProcessUspdInTree(result,uspdList, isFilteredBySmallTi, isHideTi); //} #if DEBUG sw.Stop(); Console.WriteLine("Построение дерева {0} млс", sw.ElapsedMilliseconds); #endif return(result); }
/// <summary> /// Основная процедура группового выделения объектов на дереве /// </summary> /// <param name="isSelect">Выделить/снять</param> /// <param name="isRecursive">Включая дочерние</param> /// <param name="items">Список объектов</param> /// <param name="itemType">Тип объекта для выбора</param> public void SelectUnselect(bool isSelect, bool isRecursive, IEnumerable <FreeHierarchyTreeItem> items, EnumFreeHierarchyItemType?itemType = null, int?maxlevel = null) { if (items == null) { return; } //Объекты, которые нужно предварительно подготовить, прежде чем выделять там дочерние var itemsForPrepare = new List <FreeHierarchyTreeItem>(); //Объекты у которых меняются чек боксы о том что там выделены дочерние var itemsByLevForUpdateChekbox = new Dictionary <int, HashSet <int> >(); //Объекты у которых нужно уведомить визуальку что изменились статусы var selectedItems = new List <FreeHierarchyTreeItem>(); if (!_treeItemsSyncLock.TryEnterWriteLock(_maxLockWait)) { return; } try { var currLevel = 0; //Выделяем доступные объекты foreach (var treeItem in items.OrderByDescending(i => i.HierLevel)) { treeItem.SelectUnselect(isSelect, itemsForPrepare, itemsByLevForUpdateChekbox, isRecursive, itemType, maxlevel, selectedItems); } if (isSelect) { //foreach(var itemsForPrepareGroupByType in itemsForPrepare // .GroupBy(g=>g.FreeHierItemType) // .OrderByDescending(o=>o.Key)) //Подготавливаем недоступные объекты и потом выделяем //Рекурсивная подготовка дочерних объектов do { //Подгружаем внутренние словари для определения количества FreeHierarchyTreePreparer.PrepareGlobalDictionaries(itemsForPrepare, EnumFreeHierarchyTreePrepareMode.All); //Формируем дочерние узлы у прогруженных объектов, для того, чтобы идти дальше вниз по дереву LoadDynamicChildren(itemsForPrepare); var newitems = itemsForPrepare.ToList(); itemsForPrepare.Clear(); foreach (var item in newitems) { item.SelectChildren(true, itemsForPrepare, itemsByLevForUpdateChekbox, isRecursive, itemType, true, selectedItems: selectedItems, currLevel: currLevel, maxlevel: maxlevel); } currLevel++; } while (itemsForPrepare.Count > 0); } } catch (Exception ex) { Manager.UI.ShowMessage(ex.ToString()); } finally { _treeItemsSyncLock.ExitWriteLock(); } //Уведомляем визуалку что изменились состояния объектов на дереве FreeHierarchyTree.InvokeAsync(() => { //Проставляем чек боксы на родителя у которых выделены дочерние ProcessParentCheckboxes(itemsByLevForUpdateChekbox); //Уведомляем визуалку что изменились статусы выделения RaiseSelectedItemsChanged(selectedItems); }); }
private Tuple <List <IDHierarchy>, string, CancellationToken> InvokeSearch(string text, string parentText, enumTypeHierarchy?typeHierarchy, CancellationToken token) { var needFindTI = _descriptor.NeedFindTI; var needFindUaNode = _descriptor.NeedFindUaNode; var needFindTransformatorsAndreactors = _descriptor.NeedFindTransformatorsAndreactors; //Необходим поиск трансформаторов и реакторов по базе (т.к. еще не подгрузились) var freeHierTreeId = _descriptor.Tree_ID ?? -101; var findUspdAndE422InTree = _descriptor.ShowUspdAndE422InTree; var tiComparer = new IFreeHierarchyObjectComparerTyped(); var objectComparer = new HierarchyObjectFoundedComparer(); var foundedObjects = new ConcurrentStack <IDHierarchy>(); #if DEBUG System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); #endif Parallel.Invoke(() => { //if (_findTiType == EnumFindTiType.Pik) return; try { //поиск прочих объектов var hierObjects = ARM_Service.TREE_FindHierObject(text, parentText, Manager.User.User_ID, freeHierTreeId, _findTiType.ToString(), findUspdAndE422InTree, typeHierarchy); if (hierObjects != null && hierObjects.Count > 0) { foundedObjects.PushRange(hierObjects.OrderBy(h => h.TypeHierarchy).ThenByDescending(h => h, objectComparer).ToArray()); } } catch (Exception ex) { Manager.UI.ShowMessage(ex.Message); } }, () => { if (!needFindTransformatorsAndreactors) { return; } try { //Поиск трансформаторов и реакторов var reactorsAndTransformators = ServiceFactory.ArmServiceInvokeSync <Tuple <List <Hard_PTransformator>, List <Hard_PReactors> > >("TREE_TransformatorOrReactor", text); if (reactorsAndTransformators != null) { if (reactorsAndTransformators.Item1 != null) { reactorsAndTransformators.Item1.ForEach(transformator => { foundedObjects.Push( EnumClientServiceDictionary.GetOrAddTransformator(transformator.PTransformator_ID, transformator)); }); } if (reactorsAndTransformators.Item2 != null) { reactorsAndTransformators.Item2.ForEach(reactor => { foundedObjects.Push( EnumClientServiceDictionary.GetOrAddReactor(reactor.PReactor_ID, reactor)); }); } } } catch (Exception ex) { Manager.UI.ShowMessage(ex.Message); } }, () => { //Поиск узлов OPC на дереве if (!needFindUaNode) { return; } try { var opcNodes = UAService.Service.UA_FindNode(text, freeHierTreeId, _findTiType == EnumFindTiType.MeterSerialNumber ? "UANode_ID" : null); // "UANode_ID" if (opcNodes != null && opcNodes.Count > 0) { //Предварительная прогрузка узлов с типами найденных узлов (чтобы визуалка не тормозила) UAHierarchyDictionaries.UANodesDict.Prepare(new HashSet <long>(opcNodes .Where(fn => fn.Node.UATypeNode_ID.HasValue) .Select(fn => fn.Node.UATypeNode_ID.Value))); foundedObjects.PushRange(opcNodes.ToArray()); } } catch (Exception ex) { Manager.UI.ShowMessage(ex.Message); } }); #if DEBUG sw.Stop(); Console.WriteLine("Поиск {0} млс", sw.ElapsedMilliseconds); #endif //Отмена поиска if (token.IsCancellationRequested) { return(null); } //Подготавливаем словари Task.Factory.StartNew(() => FreeHierarchyTreePreparer.PrepareGlobalDictionaries(foundedObjects, token: token)); return(new Tuple <List <IDHierarchy>, string, CancellationToken>(foundedObjects.OrderByDescending(d => d.TypeHierarchy).ToList(), text, token)); }