Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- private TreePropertyControl TreePropertyControl
- {
- get { return Customizable.FindPropertyItem<TreePropertyControl>("TreeReferences"); }
- }
- private ReferenceList referenceList;
- internal ReferenceList ReferenceList
- {
- get
- {
- return referenceList ?? (referenceList = ((Document)BaseObject).MainInfo.ReferenceList);
- }
- }
- private ReferenceListView RefListView
- {
- get { return (ReferenceListView)Customizable.LayoutControl.GetControlByName("References"); }
- }
- internal bool IsTreeLoaded;//флаг того, что дерево загружено
- private int _lastPreviewedNodeHandle = 0;//указатель на предыдущий просмотренный нод
- //(может пригодиться, если понадобится сделать предпросмотр карточек, скрывающихся за нодами)
- private int _prevRowCount = -1;//для отслеживания изменений в списке карточек и дальнейшей перерисовки дерева
- private decimal _priceCounter;//опциональный счётчик. В данном примере считает цену дополнительных договоров
- /// <summary>
- /// Обновление дерева
- /// </summary>
- private void RefreshTree()
- {
- if (TreePropertyControl == null) return;
- TreePropertyControl.Enabled = false;
- TreePropertyControl.Visible = false;
- TreePropertyControl.userTreeList.Visible = false;
- TreePropertyControl.userTreeList.Enabled = false;
- ActivateTree();
- Thread.Sleep(1000);
- TreePropertyControl.userTreeList.Visible = true;
- TreePropertyControl.userTreeList.Enabled = true;
- TreePropertyControl.Enabled = true;
- TreePropertyControl.Visible = true;
- }
- /// <summary>
- /// Активация и первоначальное наполнение дерева
- /// </summary>
- public void ActivateTree()
- {
- var treeList = TreePropertyControl.userTreeList;//DevExpress.XtraTreeList
- if (treeList == null)
- {
- Messages.TraceMessage("TreePropertyControl.userTreeList is null");
- return;
- }
- if (treeList.Columns.Count < 2)
- {
- //treeList.Columns.Clear();
- var columnDescr = treeList.Columns[0];//0
- columnDescr.Name = "Description";
- columnDescr.Caption = "Description";
- columnDescr.OptionsColumn.ReadOnly = true;//все столбцы сделаем нередактируемыми
- columnDescr.VisibleIndex = 0;//номер видимого столбца по порядку с 0
- columnDescr.Visible = true;
- var newColumn1 = treeList.Columns.Add();//1
- newColumn1.Name = "Initiator";
- newColumn1.Caption = "Initiator";
- newColumn1.OptionsColumn.ReadOnly = true;
- newColumn1.VisibleIndex = 1;
- newColumn1.Visible = true;
- var newColumn2 = treeList.Columns.Add();//2
- newColumn2.Name = "Card";
- newColumn2.Caption = "Card";
- newColumn2.OptionsColumn.ReadOnly = true;
- newColumn2.Visible = false;//столбец, в котором будем хранить Id карточки
- var newColumn3 = treeList.Columns.Add();//3
- newColumn3.Name = "Price";
- newColumn3.Caption = "Price";
- newColumn3.OptionsColumn.ReadOnly = true;
- newColumn3.VisibleIndex = 2;
- newColumn3.Visible = true;
- treeList.OptionsView.ShowColumns = true;
- }
- if (treeList.SelectImageList == null)
- {
- var imgCollection = new ImageCollection();
- imgCollection.AddImage(Resources.Resources.CardDocument.ToBitmap());//0-ой элемент в коллекции - иконка карточки документа
- treeList.SelectImageList = imgCollection;
- }
- if (treeList.Nodes != null)
- treeList.Nodes.Clear();
- var doc = GetRootContractDocument(BaseObject as Document);//получим корневой договор (нет родителей, несколько дочерних "приложений")
- if (doc == null) return;
- var docId = Context.GetObjectRef(doc).Id;
- if (doc.MainInfo.ReferenceList == null)
- {
- doc.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();//создадим список ссылок, если нет
- }
- referenceList = doc.MainInfo.ReferenceList;
- if (!IsTreeLoaded)
- {
- TreePropertyControl.NodeDoubleClicked += TreeReferences_NodeDoubleClicked;//ивент даблклика на нод
- treeList.FocusedNodeChanged += TreeList_FocusedNodeChanged;//ивент для предпросмотра сведений о карточке
- if (RefListView != null)
- {
- _prevRowCount = ReferenceList.References.Count;
- RefListView.ListChanged += RefListView_ListChanged;//событие измения списка ссылок в стандартном контроле "Ссылки". Если пользователь добавил/удалил ссылку
- }
- IsTreeLoaded = true;
- }
- treeList.BeginUnboundLoad();
- var parentNode =
- treeList.AppendNode(
- new object[]//в этом массиве объектов: 0ой объект - описание, 1ый - инициатор договора, 2 - Id карточки, 3 - цена
- {
- string.IsNullOrEmpty(doc.Description) ? "<empty description>" : doc.Description,
- doc.GetContractInitiator().HasValue? StaffService.Get(doc.GetContractInitiator().Value).ToString():"<empty initiator>"
- //получим инициатора договора (из динамической секции) с помощью метода расширения
- //(см. https://msdn.microsoft.com/en-us/library/vstudio/bb383977(v=vs.110).aspx)
- },
- null);//нод 1го уровня
- parentNode.ImageIndex = 0;//иконка документа
- parentNode.SelectImageIndex = 0;
- int counter = 0;//счётчик вложенности дерева для избежания бесконечности
- _priceCounter = 0;//обнуление счётчика цены
- FillTree(parentNode, treeList, docId, docId, counter);//наполнение дерева нодами
- #region count total price
- treeList.AppendNode(//последняя строка(нод) в дереве
- new object[]
- {
- "Total price:",
- string.Empty,
- null,
- _priceCounter
- }, null);
- #endregion
- treeList.EndUnboundLoad();
- ExpandTreeListNodesToLevel(treeList.Nodes, 2);//раскроем дерево до определённого уровня
- if (treeList.Enabled) return;
- treeList.Enabled = true;
- }
- /// <summary>
- /// Событие изменения списка ссылок
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public void RefListView_ListChanged(object sender, EventArgs e)
- {
- var doc = (Document)CardControl.BaseObject;
- if (doc.MainInfo.ReferenceList != null)
- {
- referenceList = doc.MainInfo.ReferenceList;
- try
- {
- if (_prevRowCount > ReferenceList.References.Count) //удалено
- {
- Context.SaveObject(ReferenceList);//saved
- RefreshReferenceList();//обновим ReferenceList
- RefreshTree();//обновим само дерева
- _prevRowCount = ReferenceList.References.Count;//обновим счётчик
- }
- else//добавлено
- //особенности поведения ReferenceList-а
- {
- //RefreshReferenceList();
- RefreshTree();
- _prevRowCount = ReferenceList.References.Count;
- }
- }
- catch (Exception ex)
- {
- Messages.InformationMessage("Произошла ошибка при обновлении дерева связей: " + ex.ToString());
- }
- }
- }
- /// <summary>
- /// Обновление ReferenceList
- /// </summary>
- private void RefreshReferenceList()
- {
- var doc = (Document)CardControl.BaseObject;
- if (ReferenceList != null)
- {
- Context.GetObjectRef<ReferenceList>(ReferenceList);
- Context.RefreshObject<ReferenceList>(ref referenceList);
- doc.MainInfo.ReferenceList = ReferenceList;
- }
- }
- /// <summary>
- /// Наполнить дерево
- /// </summary>
- /// <param name="parentNode"></param>
- /// <param name="tl"></param>
- /// <param name="cardId"></param>
- /// <param name="prevCardId"></param>
- /// <param name="counter"></param>
- private void FillTree(TreeListNode parentNode, TreeList tl, Guid cardId, Guid prevCardId, int counter)
- {
- counter++;//предотвращает бесконечную глубину дерева (из-за прямых-обратных ссылок)
- var document = Context.GetObject<Document>(cardId);
- if (document == null) return;
- if (document.MainInfo.ReferenceList == null)
- document.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();
- var refListRefs = document.MainInfo.ReferenceList.References.Where(i=>i.Type==ChildContract).Select(i=>i).ToList();//сделаем выборку
- //ChildContract - экземпляр LinksLinkType взятый из контекста по Id
- for (int i = refListRefs.Count - 1; i > -1; i--)
- {
- if (refListRefs[i].Card == Guid.Empty)
- {
- document.MainInfo.ReferenceList.References.Remove(refListRefs[i]);//удаляем пустые ссылки
- refListRefs.RemoveAt(i);//удалим из выборки
- continue;
- }
- bool flag = false;
- TreeListNode tlnLink = null;
- //if (parentNode.HasChildren)//блок кода, если надо группировать по нескольким типам связи, а не по одному
- //{
- // foreach (TreeListNode node in parentNode.Nodes)
- // if (node.GetDisplayText(0) == refListRefs[i].Type.DisplayName)
- // {
- // flag = true;
- // tlnLink = node;//если уже есть нод связи, запоминаем
- // }
- //}
- bool isReverseLink = (refListRefs[i].Card == prevCardId);
- //if (!flag && !isReverseLink)
- //{
- // tlnLink = CreateNode(tl, new object[] { refListRefs[i].Type.DisplayName }, parentNode.Id, 2, 2, 2);
- // //нод связи создаём, если новая встретившаяся связь
- //}
- if (CardDocument.ID == refListRefs[i].CardType && !isReverseLink)
- {
- var newNodeDoc = Context.GetObject<Document>(refListRefs[i].Card);
- var euroPrice = newNodeDoc.GetEuroPriceDr();//метод расширения для получения суммы договора в евро
- _priceCounter += euroPrice;
- var tlnCard = CreateNode(tl,
- new object[]
- {
- refListRefs[i].CardDescription,
- newNodeDoc.GetContractInitiator().HasValue? StaffService.Get(newNodeDoc.GetContractInitiator().Value).ToString():"<empty initiator>",
- refListRefs[i].Card,
- euroPrice
- },
- parentNode.Id, 0, 0, 0);//создаём нод документа, указывая родительский нод
- if (counter < 3)//проверка глубины
- FillTree(tlnCard, tl, refListRefs[i].Card, cardId, counter);//на уровень ниже
- }
- }
- }
- /// <summary>
- /// Создать нод дерева
- /// </summary>
- /// <param name="tl"></param>
- /// <param name="nodeData"></param>
- /// <param name="parentNodeId"></param>
- /// <param name="imageIndex"></param>
- /// <param name="selectImageIndex"></param>
- /// <param name="stateImageIndex"></param>
- /// <returns></returns>
- private TreeListNode CreateNode(TreeList tl, object nodeData, int parentNodeId, int imageIndex,
- int selectImageIndex, int stateImageIndex)
- {
- return tl.AppendNode(nodeData, parentNodeId, imageIndex, selectImageIndex, stateImageIndex);
- }
- private void ExpandTreeListNodesToLevel(TreeListNodes nodes, int level)
- {
- foreach (TreeListNode node in nodes)
- {
- node.Expanded = true;
- if (node.HasChildren && node.Level < level - 1)
- ExpandTreeListNodesToLevel(node.Nodes, level);
- }
- }
- /// <summary>
- /// Показ карточки по дабл клику
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void TreeReferences_NodeDoubleClicked(object sender, Docsvision.TreeControl.NodeEventArgs e)
- {
- var id = e.LeftMouseButtonPressed && e.Node.GetValue(2) != null//2 == CardId column (invisible)
- ? DoGuid(e.Node.GetValue(2).ToString())
- : Guid.Empty;
- if (id != Guid.Empty && id != CardData.Id)
- {
- var baseCard = Context.GetObject<BaseCard>(id);
- if (AccessCheckingService.IsOperationAllowed(baseCard, BaseCard.ReadOperation))
- CardFrame.CardHost.ShowCard(id, ActivateMode.Edit);
- else
- {
- //Если нельзя читать карточку, то сообщим каким ролям принадлежит пользователь
- UiService.ShowError(Resources.Resources.InsufficientReadCard + Environment.NewLine +
- "Roles:" +
- string.Join(";",
- AccessCheckingService.GetUserRoles(baseCard,
- StaffService.GetCurrentEmployee()).Select(i => i.Name)));
- }
- }
- var tree = sender as TreePropertyControl;
- if (tree != null)
- {
- tree.NodeDoubleClicked -= TreeReferences_NodeDoubleClicked;
- //так надо, потому что иногда дабл клик перестаёт работать (*DV ...)
- tree.NodeDoubleClicked += TreeReferences_NodeDoubleClicked;
- }
- }
- /// <summary>
- /// Выбор нода
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void TreeList_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
- {
- if (e.Node == null) return;
- //событие выбора нода
- }
- /// <summary>
- /// Получение корневого договора
- /// </summary>
- /// <param name="doc"></param>
- /// <returns></returns>
- public Document GetRootContractDocument(Document doc)
- {
- Document root = null;
- if (doc.MainInfo.ReferenceList == null)
- doc.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();
- var refList = doc.MainInfo.ReferenceList;
- var allParents = refList.References.Where(i => i.CardType == CardDocument.ID && i.Type == ParentContract);
- var allParentsList = allParents as ReferenceListReference[] ?? allParents.ToArray();
- if (allParentsList.Count() > 1)
- {
- UiService.ShowError("This contract attachment already has parent contract." + Environment.NewLine +
- "Contract attachment can't have more than one parent");
- }
- else
- {
- if (allParentsList.Any())
- {
- var upLevelDoc = Context.GetObject<Document>(allParentsList.FirstOrDefault().Card);
- if (upLevelDoc != null)
- root = GetRootContractDocument(upLevelDoc);
- }
- else
- {
- root = doc;
- }
- }
- return root;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement