public void Expand()
        {
            if (!IsEnabled())
            {
                throw new ElementNotEnabledException();
            }

            MultiSelectTreeViewItem treeViewItem = (MultiSelectTreeViewItem)Owner;

            if (!treeViewItem.HasItems)
            {
                throw new InvalidOperationException("Cannot expand because item has no children.");
            }

            treeViewItem.IsExpanded = true;
        }
        /// <summary>
        /// Overridden because original wpf tree does show the expander button and the contents of the
        /// header as children, too. That was requested by the users.
        /// </summary>
        /// <returns>Returns a list of children.</returns>
        protected override List <AutomationPeer> GetChildrenCore()
        {
            //System.Diagnostics.Trace.WriteLine("MultiSelectTreeViewItemAutomationPeer.GetChildrenCore()");
            MultiSelectTreeViewItem owner = (MultiSelectTreeViewItem)Owner;

            List <AutomationPeer> children = new List <AutomationPeer>();
            var button = owner.Template.FindName("Expander", owner) as ToggleButton;

            AddAutomationPeer(children, button);
            //System.Diagnostics.Trace.WriteLine("- Adding ToggleButton, " + (button == null ? "IS" : "is NOT") + " null, now " + children.Count + " items");

            var contentPresenter = GetContentPresenter(owner);

            if (contentPresenter != null)
            {
                int childrenCount = VisualTreeHelper.GetChildrenCount(contentPresenter);
                for (int i = 0; i < childrenCount; i++)
                {
                    var child = VisualTreeHelper.GetChild(contentPresenter, i) as UIElement;
                    AddAutomationPeer(children, child);
                    //System.Diagnostics.Trace.WriteLine("- Adding child UIElement, " + (child == null ? "IS" : "is NOT") + " null, now " + children.Count + " items");
                }
            }

            ItemCollection items = owner.Items;

            for (int i = 0; i < items.Count; i++)
            {
                MultiSelectTreeViewItem treeViewItem = owner.ItemContainerGenerator.ContainerFromIndex(i) as MultiSelectTreeViewItem;
                AddAutomationPeer(children, treeViewItem);
                //System.Diagnostics.Trace.WriteLine("- Adding MultiSelectTreeViewItem, " + (treeViewItem == null ? "IS" : "is NOT") + " null, now " + children.Count + " items");
            }

            if (children.Count > 0)
            {
                //System.Diagnostics.Trace.WriteLine("MultiSelectTreeViewItemAutomationPeer.GetChildrenCore(): returning " + children.Count + " children");
                //for (int i = 0; i < children.Count; i++)
                //{
                //    System.Diagnostics.Trace.WriteLine("- Item " + i + " " + (children[i] == null ? "IS" : "is NOT") + " null");
                //}
                return(children);
            }

            //System.Diagnostics.Trace.WriteLine("MultiSelectTreeViewItemAutomationPeer.GetChildrenCore(): returning null");
            return(null);
        }
        private bool DealHover(
            ItemsControl targetItemsControl, IList <TestModel> targetCollection, int targetIndex,
            IList <TestModel> sourceCollection, int sourceIndex, TestModel sourceItem,
            int newGroupIndex, MultiSelectTreeViewItem overlapContainer,
            ref MultiSelectTreeViewItem lastOverlapContainer, ref DateTime startOverlapTime)
        {
            if (!(targetItemsControl is MultiSelectTreeView))
            {
                return(false);
            }

            if (lastOverlapContainer != overlapContainer)
            {
                lastOverlapContainer = overlapContainer;
                startOverlapTime     = DateTime.Now;
            }

            if ((DateTime.Now - startOverlapTime).TotalMilliseconds > 1200)
            {
                var targetItem = targetCollection[targetIndex];

                var group = new TestModel {
                    Name = "New Group", IsGroup = true
                };
                group.ModelCollection.Add(targetItem);
                group.ModelCollection.Add(sourceItem);

                targetCollection.RemoveAt(targetIndex);
                targetCollection.Insert(targetIndex, group);

                sourceCollection.RemoveAt(sourceIndex);

                var newGroupGenerator = (ContainerFromIndex(targetItemsControl, newGroupIndex) as ItemsControl).ItemContainerGenerator;
                CheckNewGroupContainerGenerator(newGroupGenerator);

                lastOverlapContainer = null;
            }

            return(true);
        }
        public void SetValue(string value)
        {
            try
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    return;
                }

                string[] ids = value.Split(new[] { ';' });

                object obj;
                if (ids.Length > 0 && ids[0] == "Context")
                {
                    MultiSelectTreeViewItem treeViewItem = (MultiSelectTreeViewItem)Owner;
                    obj = treeViewItem.DataContext;
                }
                else
                {
                    obj = Owner;
                }

                if (ids.Length < 2)
                {
                    requestedValue = obj.ToString();
                }
                else
                {
                    Type         type = obj.GetType();
                    PropertyInfo pi   = type.GetProperty(ids[1]);
                    requestedValue = pi.GetValue(obj, null).ToString();
                }
            }
            catch (Exception ex)
            {
                requestedValue = ex.ToString();
            }
        }
        private void CheckNewGroupContainerGenerator(ItemContainerGenerator newGroupGenerator)
        {
            if (newGroupGenerator.Status < GeneratorStatus.ContainersGenerated)
            {
                EventHandler handler = null;
                handler = (s, e) =>
                {
                    var generator = (ItemContainerGenerator)s;

                    if (_draggingContainer == null)
                    {
                        generator.StatusChanged -= handler;
                    }
                    else
                    {
                        if (generator.Status == GeneratorStatus.ContainersGenerated)
                        {
                            _draggingContainer = generator.ContainerFromIndex(1) as MultiSelectTreeViewItem;
                            if (_draggingContainer != null)
                            {
                                _draggingContainer.Focus();
                                _draggingContainer.Opacity = 0.2;
                            }

                            generator.StatusChanged -= handler;
                        }
                    }
                };

                newGroupGenerator.StatusChanged += handler;
            }
            else
            {
                _draggingContainer = newGroupGenerator.ContainerFromIndex(1) as MultiSelectTreeViewItem;
            }
        }
Exemplo n.º 6
0
		/// <summary>
		/// Select all nodes between the two nodes given in the arguments. The two nodes might be given in arbitrary order and at arbitrary levels.
		/// </summary>
		/// <param name="item1">One node.</param>
		/// <param name="item2">The other node.</param>
		/// <param name="includingIndirectChildNodes"></param>
		public static void SelectAllNodesInbetween(MultiSelectTreeViewItem item1, MultiSelectTreeViewItem item2, bool includingIndirectChildNodes)
		{
			int level1 = item1.GetDepth();
			int level2 = item2.GetDepth();

			// swap item1 and item2, so that item2 is the item with the higher level
			if (level1 > level2)
			{
				var hi = item1;
				var hl = level1;
				item1 = item2;
				level1 = level2;
				item2 = hi;
				level2 = hl;
			}

			// get the parent node of item2, that is on the same level than item1
			var item2OnLevel1 = item2; //
			for (int l = level2 - 1; l >= level1; --l)
				item2OnLevel1 = (MultiSelectTreeViewItem)item2OnLevel1.ParentItemsControl;

			// to determine which node is the first node and which the last node, find
			// the common anchestor of both nodes

			var it1 = item1;
			var it2 = item2OnLevel1;
			while (it1.ParentItemsControl != it2.ParentItemsControl)
			{
				it1 = it1.ParentItemsControl as MultiSelectTreeViewItem;
				it2 = it2.ParentItemsControl as MultiSelectTreeViewItem;
			}

			// now we can determine which node is first and which last
			// if both are identical, then item1 is the first item, since
			// parent nodes comes first compared to child nodes

			var commonParent = it1.ParentItemsControl;
			int idx1 = commonParent.ItemContainerGenerator.IndexFromContainer(it1);
			int idx2 = commonParent.ItemContainerGenerator.IndexFromContainer(it2);
			bool item1IsFirst = idx1 <= idx2;

			// Swap so that item1 gets the first item
			if (!item1IsFirst)
			{
				var hi = item1;
				var hl = level1;
				var hh = it1;
				var hx = idx1;

				item1 = item2;
				level1 = level2;
				it1 = it2;
				idx1 = idx2;

				item2 = hi;
				level2 = hl;
				it2 = hh;
				idx2 = hx;
			}

			// if item1 and item2 share the same anchestor, select from item1 to items
			if (item1.ParentItemsControl == commonParent && item2.ParentItemsControl == commonParent)
			{
				SelectAllChildNodesBetweenIndices(commonParent, idx1, idx2);
			}
			else
			{
				// first go down to the common anchestor, and then up
				var current = item1;
				current.IsSelected = true;
				var parent = current.ParentItemsControl;
				while (parent != commonParent)
				{
					int idx = parent.ItemContainerGenerator.IndexFromContainer(current);
					SelectAllChildNodesBetweenIndexAndEnd(parent, idx + 1);
					current = parent as MultiSelectTreeViewItem;
					parent = current.ParentItemsControl;
				}

				// now select all items between idx1+1 and idx2-1 (including all childs)
				SelectAllChildNodesBetweenIndices(commonParent, idx1 + 1, idx2 - 1);

				// last select from item2 downwards to the common anchestor
				current = item2;
				parent = current.ParentItemsControl;
				while (parent != commonParent)
				{
					int idx = parent.ItemContainerGenerator.IndexFromContainer(current);
					SelectAllChildNodesBetweenStartAndIndex(parent, idx);
					current = parent as MultiSelectTreeViewItem;
					parent = current.ParentItemsControl;
				}
				current.IsSelected = true;
			}
		}
Exemplo n.º 7
0
		/// <summary>
		/// Retrieve the subsequent node that is at the same level.
		/// </summary>
		/// <param name="item">The node starting with you want to retrieve the subsequent one.</param>
		/// <returns>Null if there is no subsequent node at the same level.</returns>
		public static MultiSelectTreeViewItem GetNextNodeAtSameLevel(MultiSelectTreeViewItem item)
		{
			if (item == null)
				return null;

			MultiSelectTreeViewItem nextNodeAtSameLevel = null;

			ItemsControl parentControl = item.ParentItemsControl;
			if (parentControl != null)
			{
				int index = parentControl.ItemContainerGenerator.IndexFromContainer(item);
				if (index != parentControl.Items.Count - 1) // if this is not the last item
				{
					nextNodeAtSameLevel = parentControl.ItemContainerGenerator.ContainerFromIndex(index + 1) as MultiSelectTreeViewItem;
				}
			}

			return nextNodeAtSameLevel;
		}
Exemplo n.º 8
0
		/// <summary>
		/// Retrieve the last displayed child node of the given one.
		/// </summary>
		/// <param name="item">The node starting with you want to retrieve the last visible node.</param>
		/// <returns>The last child node that is displayed, or the node itself in case it is not expanded.</returns>
		public static MultiSelectTreeViewItem GetLastVisibleChildNodeOf(MultiSelectTreeViewItem item)
		{
			MultiSelectTreeViewItem lastVisibleNode = item;

			// Retrieving last child of last expanded node
			while (lastVisibleNode != null && lastVisibleNode.Items.Count > 0 && lastVisibleNode.IsExpanded)
				lastVisibleNode = lastVisibleNode.ItemContainerGenerator.ContainerFromIndex(lastVisibleNode.Items.Count - 1) as MultiSelectTreeViewItem;

			return lastVisibleNode;
		}
        private bool MoveDown(MultiSelectTreeView rootTreeView, Rect draggingRect, ref MultiSelectTreeViewItem draggingContainer, ref MultiSelectTreeViewItem lastOverlapContainer, ref DateTime startOverlapTime)
        {
            Size overlapSize     = new Size();
            Rect overlapItemRect = new Rect();
            MultiSelectTreeViewItem overlapContainer = null;

            var sourceItemsControl = ItemsControl.ItemsControlFromItemContainer(draggingContainer);

            if (sourceItemsControl == null)
            {
                return(false);
            }

            var sourceCollection = sourceItemsControl.ItemsSource as IList <TestModel>;
            var sourceIndex      = sourceItemsControl.ItemContainerGenerator.IndexFromContainer(draggingContainer);
            var sourceItem       = sourceCollection[sourceIndex];

            var sourcePos = draggingContainer.TranslatePoint(new Point(), rootTreeView);

            //从组中分离
            if (IsFromGroup(sourceItemsControl) && sourceIndex == sourceItemsControl.Items.Count - 1 && DoubleUtil.GreaterThan(draggingRect.Y, sourcePos.Y + draggingContainer.ActualHeight / 2))
            {
                //加入上层集合
                var superItemsControl = ItemsControl.ItemsControlFromItemContainer(sourceItemsControl);
                var superCollection   = superItemsControl.ItemsSource as IList <TestModel>;
                var superIndex        = superItemsControl.ItemContainerGenerator.IndexFromContainer(sourceItemsControl);

                sourceCollection.RemoveAt(sourceIndex);
                if (superIndex + 1 < superItemsControl.Items.Count)
                {
                    superCollection.Insert(superIndex + 1, sourceItem);
                    draggingContainer = ContainerFromIndex(superItemsControl, superIndex + 1) as MultiSelectTreeViewItem;
                }
                else
                {
                    superCollection.Add(sourceItem);
                    draggingContainer = ContainerFromIndex(superItemsControl, superCollection.Count - 1) as MultiSelectTreeViewItem;
                }

                //原组若剩余一项,则将该项加入上层集合,移除组
                if (sourceItemsControl.Items.Count == 1)
                {
                    sourceItem = sourceCollection[0];
                    sourceCollection.RemoveAt(0);

                    superCollection.Insert(superIndex + 1, sourceItem);
                    superCollection.RemoveAt(superIndex);
                }

                lastOverlapContainer = null;
                return(true);
            }

            if (!FindFirstDownItemWithValidOverlap(rootTreeView, sourceItemsControl, sourceIndex + 1, draggingContainer, draggingRect, ref overlapSize, ref overlapItemRect, ref overlapContainer))
            {
                return(false);
            }

            var targetItemsControl = ItemsControl.ItemsControlFromItemContainer(overlapContainer);
            var targetCollection   = targetItemsControl.ItemsSource as IList <TestModel>;
            var targetIndex        = targetItemsControl.ItemContainerGenerator.IndexFromContainer(overlapContainer);

            if (DoubleUtil.LessThan(draggingRect.Bottom, overlapItemRect.Y + overlapItemRect.Height / 2))
            {
                //Do noting
            }
            else if (DoubleUtil.LessThan(draggingRect.Bottom, overlapItemRect.Y + overlapItemRect.Height * 3 / 4)) // 1/4 -> 3/4 height
            {
                //非同组,则加入
                if (IsFromGroup(targetItemsControl) && targetItemsControl != sourceItemsControl)
                {
                    sourceCollection.RemoveAt(sourceIndex);
                    targetCollection.Insert(0, sourceItem);

                    lastOverlapContainer = null;
                    draggingContainer    = ContainerFromIndex(targetItemsControl, 0) as MultiSelectTreeViewItem;
                }
            }
            else if (DoubleUtil.GreaterThan(draggingRect.Y, overlapItemRect.Y + overlapItemRect.Height / 4)) //Top -> 1/4 height 移动
            {
                sourceCollection.RemoveAt(sourceIndex);
                targetCollection.Insert(targetIndex, sourceItem);

                lastOverlapContainer = null;
                draggingContainer    = ContainerFromIndex(targetItemsControl, targetIndex) as MultiSelectTreeViewItem;
            }
            else //处理悬停,创建新组
            {
                if (!DealHover(
                        targetItemsControl, targetCollection, targetIndex,
                        sourceCollection, sourceIndex, sourceItem,
                        targetIndex - 1, overlapContainer,
                        ref lastOverlapContainer, ref startOverlapTime))
                {
                    return(false);
                }
            }

            return(true);
        }
        private bool FindFirstDownItemWithValidOverlap(MultiSelectTreeView rootTreeView, ItemsControl parentItemsControl, int startIndex, MultiSelectTreeViewItem draggingContainer, Rect draggingRect, ref Size overlapSize, ref Rect overlapContainerRect, ref MultiSelectTreeViewItem overlapContainer)
        {
            while (startIndex < parentItemsControl.Items.Count)
            {
                var downTreeViewItem = parentItemsControl.ItemContainerGenerator.ContainerFromIndex(startIndex++) as MultiSelectTreeViewItem;
                if (downTreeViewItem == null)
                {
                    continue;
                }

                if (downTreeViewItem.HasItems &&
                    downTreeViewItem.IsExpanded     //for move over the collapsed group
                    //&& !(downTreeViewItem.DataContext as JOB_INFO).IsLocked  //for IsLocked is false
                    //&& draggingContainer.ContainDepth() + downTreeViewItem.InDepth() < LogicCenter.JobListMaxDepth //for tree depth
                    && ItemsControl.ItemsControlFromItemContainer(draggingContainer) == parentItemsControl)  //for move into first group
                {
                    if (FindFirstDownItemWithValidOverlap(rootTreeView, downTreeViewItem, 0, draggingContainer, draggingRect, ref overlapSize, ref overlapContainerRect, ref overlapContainer))
                    {
                        return(true);
                    }
                }
                else
                {
                    var downItemPos         = downTreeViewItem.TranslatePoint(new Point(), rootTreeView);
                    var downItemOverlapSize = GetOverlapSize(new Rect(downItemPos, new Point(downItemPos.X + downTreeViewItem.ActualWidth, downItemPos.Y + downTreeViewItem.ActualHeight)), draggingRect);

                    if (downItemOverlapSize.IsEmpty || DoubleUtil.IsZero(downItemOverlapSize.Width) || DoubleUtil.IsZero(downItemOverlapSize.Height))
                    {
                        continue;
                    }

                    overlapSize          = downItemOverlapSize;
                    overlapContainerRect = new Rect(downItemPos.X, downItemPos.Y, downTreeViewItem.ActualWidth, downTreeViewItem.ActualHeight);
                    overlapContainer     = downTreeViewItem;

                    return(true);
                }
            }
            ;

            var superIC = ItemsControl.ItemsControlFromItemContainer(parentItemsControl);

            if (superIC == null)
            {
                return(false);
            }

            var topIndex = superIC.ItemContainerGenerator.IndexFromContainer(parentItemsControl);

            return(FindFirstDownItemWithValidOverlap(rootTreeView, superIC, topIndex + 1, draggingContainer, draggingRect, ref overlapSize, ref overlapContainerRect, ref overlapContainer));
        }
        private static ContentPresenter GetContentPresenter(MultiSelectTreeViewItem treeViewItem)
        {
            var contentPresenter = treeViewItem.Template.FindName("PART_Header", treeViewItem) as ContentPresenter;

            return(contentPresenter);
        }
        public void Invoke()
        {
            MultiSelectTreeViewItem treeViewItem = (MultiSelectTreeViewItem)Owner;

            treeViewItem.InvokeMouseDown();
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MultiSelectTreeViewItemAutomationPeer"/>
 /// class.
 /// </summary>
 /// <param name="owner">
 /// Das <see cref="T:System.Windows.Controls.MultiSelectTreeViewItem"/>, das diesem
 /// <see cref="T:System.Windows.Automation.Peers.MultiSelectTreeViewItemAutomationPeer"/>
 /// zugeordnet ist.
 /// </param>
 public MultiSelectTreeViewItemAutomationPeer(MultiSelectTreeViewItem owner)
     : base(owner)
 {
 }