void ShowPreview(SharpTreeViewItem item, DropPlace place) { previewNodeView = item.NodeView; previewPlace = place; if (place == DropPlace.Inside) { previewNodeView.TextBackground = SystemColors.HighlightBrush; previewNodeView.Foreground = SystemColors.HighlightTextBrush; } else { if (insertMarker == null) { var adornerLayer = AdornerLayer.GetAdornerLayer(this); var adorner = new GeneralAdorner(this); insertMarker = new InsertMarker(); adorner.Child = insertMarker; adornerLayer.Add(adorner); } insertMarker.Visibility = Visibility.Visible; var p1 = previewNodeView.TransformToVisual(this).Transform(new Point()); var p = new Point(p1.X + previewNodeView.CalculateIndent() + 4.5, p1.Y - 3); if (place == DropPlace.After) { p.Y += previewNodeView.ActualHeight; } insertMarker.Margin = new Thickness(p.X, p.Y, 0, 0); SharpTreeNodeView secondNodeView = null; var index = flattener.IndexOf(item.Node); if (place == DropPlace.Before) { if (index > 0) { secondNodeView = (ItemContainerGenerator.ContainerFromIndex(index - 1) as SharpTreeViewItem).NodeView; } } else if (index + 1 < flattener.Count) { secondNodeView = (ItemContainerGenerator.ContainerFromIndex(index + 1) as SharpTreeViewItem).NodeView; } var w = p1.X + previewNodeView.ActualWidth - p.X; if (secondNodeView != null) { var p2 = secondNodeView.TransformToVisual(this).Transform(new Point()); w = Math.Max(w, p2.X + secondNodeView.ActualWidth - p.X); } insertMarker.Width = w + 10; } }
/// <summary> /// Handles the node expanding event in the tree view. /// This method gets called only if the node is in the visible region (a SharpTreeNodeView exists). /// </summary> internal void HandleExpanding(SharpTreeNode node) { if (doNotScrollOnExpanding) { return; } SharpTreeNode lastVisibleChild = node; while (true) { SharpTreeNode tmp = lastVisibleChild.Children.LastOrDefault(c => c.IsVisible); if (tmp != null) { lastVisibleChild = tmp; } else { break; } } if (lastVisibleChild != node) { Debug.Assert(flattener != null); if (flattener == null) { return; } // A new scrollViewer.ViewportHeight value is available at the earliest at Render prio. // If there are many empty lines, it will equal the number of visible items (eg. 5, // but viewport can show eg. 10). Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => { var itemsPerPage = STVUTILS.GetItemsPerPage(this, 0); int nodeIndex = flattener.IndexOf(node); int lastVisibleChildIndex = flattener.IndexOf(lastVisibleChild); Debug.Assert(nodeIndex >= 0 && lastVisibleChildIndex >= 0); if (itemsPerPage > 0 && nodeIndex >= 0 && lastVisibleChildIndex >= 0) { int lastIndex = Math.Min(lastVisibleChildIndex, nodeIndex + itemsPerPage - 1); ScrollIntoView(Items[lastIndex]); Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => ScrollIntoView(node))); } })); } }