private bool AddToSelectedElements(MultiSelectTreeViewItem treeViewItem, object item)
        {
            var index = _selectedElements.FindIndex(p => p.Container == treeViewItem);

            if (index < 0)
            {
                if (!treeViewItem.IsSelected)
                {
                    treeViewItem.IsSelected = true;
                }

                _selectedElements.Add(new ContainerItemPair(treeViewItem, item));
                return(true);
            }

            return(false);
        }
        private void FindLastVisibleTreeViewItem(MultiSelectTreeViewItem parentTreeViewItem, ref MultiSelectTreeViewItem resultTreeViewItem)
        {
            if (!parentTreeViewItem.IsVisible)
            {
                return;
            }

            if (!parentTreeViewItem.HasItems)
            {
                resultTreeViewItem = parentTreeViewItem;
                return;
            }

            FindLastVisibleTreeViewItem(
                parentTreeViewItem.ItemContainerGenerator.ContainerFromIndex(parentTreeViewItem.Items.Count - 1) as MultiSelectTreeViewItem,
                ref resultTreeViewItem);
        }
        public void ScrollToEnd()
        {
            if (!HasItems)
            {
                return;
            }

            MultiSelectTreeViewItem resultTreeViewItem = null;

            FindLastVisibleTreeViewItem(
                ItemContainerGenerator.ContainerFromIndex(Items.Count - 1) as MultiSelectTreeViewItem,
                ref resultTreeViewItem);

            if (resultTreeViewItem != null)
            {
                resultTreeViewItem.BringIntoView();
            }
        }
        internal void RemoveSelectedElement(MultiSelectTreeViewItem treeViewItem, object item, bool walkIntoSubtree)
        {
            bool flag = false;

            ForearchTreeViewItem(treeViewItem, item, walkIntoSubtree,
                                 (container, _) =>
            {
                if (RemoveFromSelectedElements(container))
                {
                    flag = true;
                }
            });

            if (flag)
            {
                SetSelectedItems();
            }
        }
        private bool RemoveFromSelectedElements(MultiSelectTreeViewItem treeViewItem)
        {
            var index = _selectedElements.FindIndex(p => p.Container == treeViewItem);

            if (index >= 0)
            {
                _selectedElements.RemoveAt(index);

                if (treeViewItem.IsSelected)
                {
                    treeViewItem.IsSelected = false;
                }

                return(true);
            }

            return(false);
        }
        public void UnselectAll()
        {
            if (_selectedElements.Count > 0)
            {
                IsChangingSelection = true;

                _selectedElements.ForEach(pair =>
                {
                    pair.Container.IsSelected = false;
                });

                _selectedElements.Clear();
                SetSelectedItems();

                _latestSelectedContainer = null;
                IsChangingSelection      = false;
            }
        }
        private static MultiSelectTreeViewItem FindLastFocusableItem(MultiSelectTreeViewItem item)
        {
            MultiSelectTreeViewItem treeViewItem = null;
            int count = -1;
            MultiSelectTreeViewItem treeViewItem1 = null;

            while (item != null)
            {
                if (!item.IsEnabled || !item.IsVisible)
                {
                    if (count <= 0)
                    {
                        break;
                    }

                    count--;
                }
                else
                {
                    if (!item.IsExpanded || !item.CanExpand)
                    {
                        return(item);
                    }

                    treeViewItem  = item;
                    treeViewItem1 = item;
                    count         = item.Items.Count - 1;
                }

                item = treeViewItem1.ItemContainerGenerator.ContainerFromIndex(count) as MultiSelectTreeViewItem;
            }

            if (treeViewItem != null)
            {
                return(treeViewItem);
            }

            return(null);
        }
        internal void ChangeSelection(object data, MultiSelectTreeViewItem container, bool selected, SelectionMode selectionMode)
        {
            IsChangingSelection = true;
            bool flag = false;

            var mode = SelectionMode == SelectionMode.Multiple ? SelectionMode.Multiple : (SelectionMode)Math.Min((int)SelectionMode, (int)selectionMode);

            if (selected)
            {
                if (mode == SelectionMode.Single)
                {
                    _selectedElements.ForEach(p => p.Container.IsSelected = false);
                    _selectedElements.Clear();
                }

                if (mode == SelectionMode.Extended)
                {
                    SelectRange(_latestSelectedContainer, container);
                    flag = true;
                }
                else
                {
                    var pair = _selectedElements.FirstOrDefault(p => p.Container == container);
                    if (pair == null)
                    {
                        if (!container.IsSelected)
                        {
                            container.IsSelected = true;
                        }

                        _selectedElements.Add(new ContainerItemPair(container, data));
                        flag = true;
                    }
                    else if (pair.Item != data)
                    {
                        pair.Item = data;
                        flag      = true;
                    }
                }
            }
            else
            {
                if (RemoveFromSelectedElements(container))
                {
                    flag = true;
                }
            }

            if (flag)
            {
                if (selected && mode != SelectionMode.Extended)
                {
                    _latestSelectedContainer = (_selectedElements == null || _selectedElements.Count == 0) ? null : _selectedElements.Last().Container;
                }

                if (!selected)
                {
                    _latestSelectedContainer = container;
                }

                SetSelectedItems();
            }

            IsChangingSelection = false;
        }
 public ContainerItemPair(MultiSelectTreeViewItem container, object item)
 {
     Container = container;
     Item      = item;
 }