Advertisement
vilgelmbb

TreePropertyControl full code

Jan 25th, 2015
725
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.46 KB | None | 0 0
  1.     private TreePropertyControl TreePropertyControl
  2.         {
  3.             get { return Customizable.FindPropertyItem<TreePropertyControl>("TreeReferences"); }
  4.         }
  5.         private ReferenceList referenceList;
  6.         internal ReferenceList ReferenceList
  7.         {
  8.             get
  9.             {
  10.                 return referenceList ?? (referenceList = ((Document)BaseObject).MainInfo.ReferenceList);
  11.             }
  12.         }
  13.         private ReferenceListView RefListView
  14.         {
  15.             get { return (ReferenceListView)Customizable.LayoutControl.GetControlByName("References"); }
  16.         }
  17.  
  18.         internal bool IsTreeLoaded;//флаг того, что дерево загружено
  19.         private int _lastPreviewedNodeHandle = 0;//указатель на предыдущий просмотренный нод
  20.         //(может пригодиться, если понадобится сделать предпросмотр карточек, скрывающихся за нодами)
  21.  
  22.         private int _prevRowCount = -1;//для отслеживания изменений в списке карточек и дальнейшей перерисовки дерева
  23.         private decimal _priceCounter;//опциональный счётчик. В данном примере считает цену дополнительных договоров
  24.  
  25.         /// <summary>
  26.         /// Обновление дерева
  27.         /// </summary>
  28.         private void RefreshTree()
  29.         {
  30.             if (TreePropertyControl == null) return;
  31.             TreePropertyControl.Enabled = false;
  32.             TreePropertyControl.Visible = false;
  33.             TreePropertyControl.userTreeList.Visible = false;
  34.             TreePropertyControl.userTreeList.Enabled = false;
  35.             ActivateTree();
  36.             Thread.Sleep(1000);
  37.             TreePropertyControl.userTreeList.Visible = true;
  38.             TreePropertyControl.userTreeList.Enabled = true;
  39.             TreePropertyControl.Enabled = true;
  40.             TreePropertyControl.Visible = true;
  41.         }
  42.  
  43.         /// <summary>
  44.         /// Активация и первоначальное наполнение дерева
  45.         /// </summary>
  46.         public void ActivateTree()
  47.         {
  48.             var treeList = TreePropertyControl.userTreeList;//DevExpress.XtraTreeList
  49.             if (treeList == null)
  50.             {
  51.                 Messages.TraceMessage("TreePropertyControl.userTreeList is null");
  52.                 return;
  53.             }
  54.            
  55.             if (treeList.Columns.Count < 2)
  56.             {
  57.                 //treeList.Columns.Clear();
  58.  
  59.                 var columnDescr = treeList.Columns[0];//0
  60.                 columnDescr.Name = "Description";
  61.                 columnDescr.Caption = "Description";
  62.                 columnDescr.OptionsColumn.ReadOnly = true;//все столбцы сделаем нередактируемыми
  63.                 columnDescr.VisibleIndex = 0;//номер видимого столбца по порядку с 0
  64.                 columnDescr.Visible = true;
  65.  
  66.                 var newColumn1 = treeList.Columns.Add();//1
  67.                 newColumn1.Name = "Initiator";
  68.                 newColumn1.Caption = "Initiator";
  69.                 newColumn1.OptionsColumn.ReadOnly = true;
  70.                 newColumn1.VisibleIndex = 1;
  71.                 newColumn1.Visible = true;
  72.  
  73.                 var newColumn2 = treeList.Columns.Add();//2
  74.                 newColumn2.Name = "Card";
  75.                 newColumn2.Caption = "Card";
  76.                 newColumn2.OptionsColumn.ReadOnly = true;
  77.                 newColumn2.Visible = false;//столбец, в котором будем хранить Id карточки
  78.  
  79.                 var newColumn3 = treeList.Columns.Add();//3
  80.                 newColumn3.Name = "Price";
  81.                 newColumn3.Caption = "Price";
  82.                 newColumn3.OptionsColumn.ReadOnly = true;
  83.                 newColumn3.VisibleIndex = 2;
  84.                 newColumn3.Visible = true;
  85.  
  86.                 treeList.OptionsView.ShowColumns = true;
  87.             }
  88.  
  89.             if (treeList.SelectImageList == null)
  90.             {
  91.                 var imgCollection = new ImageCollection();
  92.                 imgCollection.AddImage(Resources.Resources.CardDocument.ToBitmap());//0-ой элемент в коллекции - иконка карточки документа
  93.  
  94.                 treeList.SelectImageList = imgCollection;
  95.             }
  96.  
  97.             if (treeList.Nodes != null)
  98.                 treeList.Nodes.Clear();
  99.  
  100.             var doc = GetRootContractDocument(BaseObject as Document);//получим корневой договор (нет родителей, несколько дочерних "приложений")
  101.             if (doc == null) return;
  102.             var docId = Context.GetObjectRef(doc).Id;
  103.             if (doc.MainInfo.ReferenceList == null)
  104.             {
  105.                 doc.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();//создадим список ссылок, если нет
  106.             }
  107.             referenceList = doc.MainInfo.ReferenceList;
  108.  
  109.             if (!IsTreeLoaded)
  110.             {
  111.                 TreePropertyControl.NodeDoubleClicked += TreeReferences_NodeDoubleClicked;//ивент даблклика на нод
  112.                 treeList.FocusedNodeChanged += TreeList_FocusedNodeChanged;//ивент для предпросмотра сведений о карточке
  113.                 if (RefListView != null)
  114.                 {
  115.                     _prevRowCount = ReferenceList.References.Count;
  116.                     RefListView.ListChanged += RefListView_ListChanged;//событие измения списка ссылок в стандартном контроле "Ссылки". Если пользователь добавил/удалил ссылку
  117.                 }
  118.                 IsTreeLoaded = true;
  119.             }
  120.  
  121.             treeList.BeginUnboundLoad();
  122.  
  123.             var parentNode =
  124.                 treeList.AppendNode(
  125.                     new object[]//в этом массиве объектов: 0ой объект - описание, 1ый - инициатор договора, 2 - Id карточки, 3 - цена
  126.                     {
  127.                         string.IsNullOrEmpty(doc.Description) ? "<empty description>" : doc.Description,
  128.                         doc.GetContractInitiator().HasValue? StaffService.Get(doc.GetContractInitiator().Value).ToString():"<empty initiator>"
  129.                         //получим инициатора договора (из динамической секции) с помощью метода расширения
  130.                         //(см. https://msdn.microsoft.com/en-us/library/vstudio/bb383977(v=vs.110).aspx)
  131.                     },
  132.                     null);//нод 1го уровня
  133.             parentNode.ImageIndex = 0;//иконка документа
  134.             parentNode.SelectImageIndex = 0;
  135.  
  136.             int counter = 0;//счётчик вложенности дерева для избежания бесконечности
  137.             _priceCounter = 0;//обнуление счётчика цены
  138.  
  139.             FillTree(parentNode, treeList, docId, docId, counter);//наполнение дерева нодами
  140.  
  141.             #region count total price
  142.             treeList.AppendNode(//последняя строка(нод) в дереве
  143.                     new object[]
  144.                     {
  145.                         "Total price:",
  146.                         string.Empty,
  147.                         null,
  148.                         _priceCounter
  149.                     }, null);
  150.             #endregion
  151.  
  152.             treeList.EndUnboundLoad();
  153.             ExpandTreeListNodesToLevel(treeList.Nodes, 2);//раскроем дерево до определённого уровня
  154.             if (treeList.Enabled) return;
  155.             treeList.Enabled = true;
  156.         }
  157.        
  158.         /// <summary>
  159.         /// Событие изменения списка ссылок
  160.         /// </summary>
  161.         /// <param name="sender"></param>
  162.         /// <param name="e"></param>
  163.         public void RefListView_ListChanged(object sender, EventArgs e)
  164.         {
  165.             var doc = (Document)CardControl.BaseObject;
  166.             if (doc.MainInfo.ReferenceList != null)
  167.             {
  168.                 referenceList = doc.MainInfo.ReferenceList;
  169.                 try
  170.                 {
  171.                     if (_prevRowCount > ReferenceList.References.Count) //удалено
  172.                     {
  173.                         Context.SaveObject(ReferenceList);//saved
  174.                         RefreshReferenceList();//обновим ReferenceList
  175.                         RefreshTree();//обновим само дерева
  176.                         _prevRowCount = ReferenceList.References.Count;//обновим счётчик
  177.                     }
  178.                     else//добавлено
  179.                         //особенности поведения ReferenceList-а
  180.                     {
  181.                         //RefreshReferenceList();
  182.                         RefreshTree();
  183.                         _prevRowCount = ReferenceList.References.Count;
  184.                     }
  185.                 }
  186.                 catch (Exception ex)
  187.                 {
  188.                     Messages.InformationMessage("Произошла ошибка при обновлении дерева связей: " + ex.ToString());
  189.                 }
  190.             }
  191.  
  192.        
  193.         }
  194.  
  195.         /// <summary>
  196.         /// Обновление ReferenceList
  197.         /// </summary>
  198.         private void RefreshReferenceList()
  199.         {
  200.             var doc = (Document)CardControl.BaseObject;
  201.             if (ReferenceList != null)
  202.             {
  203.                 Context.GetObjectRef<ReferenceList>(ReferenceList);
  204.                 Context.RefreshObject<ReferenceList>(ref referenceList);
  205.                 doc.MainInfo.ReferenceList = ReferenceList;
  206.             }
  207.         }
  208.  
  209.         /// <summary>
  210.         /// Наполнить дерево
  211.         /// </summary>
  212.         /// <param name="parentNode"></param>
  213.         /// <param name="tl"></param>
  214.         /// <param name="cardId"></param>
  215.         /// <param name="prevCardId"></param>
  216.         /// <param name="counter"></param>
  217.         private void FillTree(TreeListNode parentNode, TreeList tl, Guid cardId, Guid prevCardId, int counter)
  218.         {
  219.             counter++;//предотвращает бесконечную глубину дерева (из-за прямых-обратных ссылок)
  220.             var document = Context.GetObject<Document>(cardId);
  221.             if (document == null) return;
  222.             if (document.MainInfo.ReferenceList == null)
  223.                 document.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();
  224.             var refListRefs = document.MainInfo.ReferenceList.References.Where(i=>i.Type==ChildContract).Select(i=>i).ToList();//сделаем выборку
  225.             //ChildContract - экземпляр LinksLinkType взятый из контекста по Id
  226.  
  227.  
  228.             for (int i = refListRefs.Count - 1; i > -1; i--)
  229.             {
  230.                 if (refListRefs[i].Card == Guid.Empty)
  231.                 {
  232.                     document.MainInfo.ReferenceList.References.Remove(refListRefs[i]);//удаляем пустые ссылки
  233.                     refListRefs.RemoveAt(i);//удалим из выборки
  234.                     continue;
  235.                 }
  236.                 bool flag = false;
  237.                 TreeListNode tlnLink = null;
  238.                 //if (parentNode.HasChildren)//блок кода, если надо группировать по нескольким типам связи, а не по одному
  239.                 //{
  240.                 //    foreach (TreeListNode node in parentNode.Nodes)
  241.                 //        if (node.GetDisplayText(0) == refListRefs[i].Type.DisplayName)
  242.                 //        {
  243.                 //            flag = true;
  244.                 //            tlnLink = node;//если уже есть нод связи, запоминаем
  245.                 //        }
  246.                 //}
  247.  
  248.                 bool isReverseLink = (refListRefs[i].Card == prevCardId);
  249.                 //if (!flag && !isReverseLink)
  250.                 //{
  251.                 //    tlnLink = CreateNode(tl, new object[] { refListRefs[i].Type.DisplayName }, parentNode.Id, 2, 2, 2);
  252.                 //    //нод связи создаём, если новая встретившаяся связь
  253.                 //}
  254.                 if (CardDocument.ID == refListRefs[i].CardType && !isReverseLink)
  255.                 {
  256.                     var newNodeDoc = Context.GetObject<Document>(refListRefs[i].Card);
  257.                     var euroPrice = newNodeDoc.GetEuroPriceDr();//метод расширения для получения суммы договора в евро
  258.                     _priceCounter += euroPrice;
  259.                     var tlnCard = CreateNode(tl,
  260.                         new object[]
  261.                         {
  262.                             refListRefs[i].CardDescription,
  263.                             newNodeDoc.GetContractInitiator().HasValue? StaffService.Get(newNodeDoc.GetContractInitiator().Value).ToString():"<empty initiator>",
  264.                             refListRefs[i].Card,
  265.                             euroPrice
  266.                         },
  267.                         parentNode.Id, 0, 0, 0);//создаём нод документа, указывая родительский нод
  268.  
  269.                     if (counter < 3)//проверка глубины
  270.                         FillTree(tlnCard, tl, refListRefs[i].Card, cardId, counter);//на уровень ниже
  271.                 }
  272.             }
  273.         }
  274.  
  275.         /// <summary>
  276.         /// Создать нод дерева
  277.         /// </summary>
  278.         /// <param name="tl"></param>
  279.         /// <param name="nodeData"></param>
  280.         /// <param name="parentNodeId"></param>
  281.         /// <param name="imageIndex"></param>
  282.         /// <param name="selectImageIndex"></param>
  283.         /// <param name="stateImageIndex"></param>
  284.         /// <returns></returns>
  285.         private TreeListNode CreateNode(TreeList tl, object nodeData, int parentNodeId, int imageIndex,
  286.             int selectImageIndex, int stateImageIndex)
  287.         {
  288.             return tl.AppendNode(nodeData, parentNodeId, imageIndex, selectImageIndex, stateImageIndex);
  289.         }
  290.  
  291.         private void ExpandTreeListNodesToLevel(TreeListNodes nodes, int level)
  292.         {
  293.             foreach (TreeListNode node in nodes)
  294.             {
  295.                 node.Expanded = true;
  296.                 if (node.HasChildren && node.Level < level - 1)
  297.                     ExpandTreeListNodesToLevel(node.Nodes, level);
  298.             }
  299.  
  300.         }
  301.  
  302.         /// <summary>
  303.         /// Показ карточки по дабл клику
  304.         /// </summary>
  305.         /// <param name="sender"></param>
  306.         /// <param name="e"></param>
  307.         private void TreeReferences_NodeDoubleClicked(object sender, Docsvision.TreeControl.NodeEventArgs e)
  308.         {
  309.             var id = e.LeftMouseButtonPressed && e.Node.GetValue(2) != null//2 == CardId column (invisible)
  310.                 ? DoGuid(e.Node.GetValue(2).ToString())
  311.                 : Guid.Empty;
  312.            
  313.             if (id != Guid.Empty && id != CardData.Id)
  314.             {
  315.                 var baseCard = Context.GetObject<BaseCard>(id);
  316.                 if (AccessCheckingService.IsOperationAllowed(baseCard, BaseCard.ReadOperation))
  317.                     CardFrame.CardHost.ShowCard(id, ActivateMode.Edit);
  318.                 else
  319.                 {
  320.             //Если нельзя читать карточку, то сообщим каким ролям принадлежит пользователь
  321.                     UiService.ShowError(Resources.Resources.InsufficientReadCard + Environment.NewLine +
  322.                                         "Roles:" +
  323.                                         string.Join(";",
  324.                                             AccessCheckingService.GetUserRoles(baseCard,
  325.                                                 StaffService.GetCurrentEmployee()).Select(i => i.Name)));
  326.  
  327.                 }
  328.             }
  329.  
  330.             var tree = sender as TreePropertyControl;
  331.             if (tree != null)
  332.             {
  333.                 tree.NodeDoubleClicked -= TreeReferences_NodeDoubleClicked;
  334.                 //так надо, потому что иногда дабл клик перестаёт работать (*DV ...)
  335.                 tree.NodeDoubleClicked += TreeReferences_NodeDoubleClicked;
  336.             }
  337.         }
  338.  
  339.         /// <summary>
  340.         /// Выбор нода
  341.         /// </summary>
  342.         /// <param name="sender"></param>
  343.         /// <param name="e"></param>
  344.         private void TreeList_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
  345.         {
  346.             if (e.Node == null) return;
  347.         //событие выбора нода
  348.         }
  349.  
  350.         /// <summary>
  351.         /// Получение корневого договора
  352.         /// </summary>
  353.         /// <param name="doc"></param>
  354.         /// <returns></returns>
  355.         public Document GetRootContractDocument(Document doc)
  356.         {
  357.             Document root = null;
  358.             if (doc.MainInfo.ReferenceList == null)
  359.                 doc.MainInfo.ReferenceList = ReferenceListService.CreateReferenceList();
  360.  
  361.             var refList = doc.MainInfo.ReferenceList;
  362.             var allParents = refList.References.Where(i => i.CardType == CardDocument.ID && i.Type == ParentContract);
  363.             var allParentsList = allParents as ReferenceListReference[] ?? allParents.ToArray();
  364.  
  365.             if (allParentsList.Count() > 1)
  366.             {
  367.                 UiService.ShowError("This contract attachment already has parent contract." + Environment.NewLine +
  368.                                     "Contract attachment can't have more than one parent");
  369.             }
  370.             else
  371.             {
  372.                 if (allParentsList.Any())
  373.                 {
  374.                     var upLevelDoc = Context.GetObject<Document>(allParentsList.FirstOrDefault().Card);
  375.                     if (upLevelDoc != null)
  376.                         root = GetRootContractDocument(upLevelDoc);
  377.                 }
  378.                 else
  379.                 {
  380.                     root = doc;
  381.                 }
  382.             }
  383.             return root;
  384.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement