/// <summary> /// Updates Offset, Viewport, and Extent. /// </summary> internal void UpdateScrollingValues(ScrollBar scrollBar) { Offset = scrollBar.Value; Viewport = scrollBar.ViewportSize; Extent = scrollBar.Maximum - scrollBar.Minimum; var parentGrid = FindControls.FindParent <ExtendedGridControl.ExtendedDataGrid>(scrollBar); if (parentGrid != null) { UpdateItem(parentGrid, true); } }
private static void AttachToEvents(DependencyObject obj, DataTemplate dataTemplate, bool vertical) { DependencyObject source = obj; var scrollViewer = FindElementOfType <ScrollViewer>(obj as FrameworkElement); if (scrollViewer != null) { string scrollBarPartName = vertical ? "PART_VerticalScrollBar" : "PART_HorizontalScrollBar"; var scrollBar = FindName <ScrollBar>(scrollBarPartName, scrollViewer); if (scrollBar != null) { var track = FindName <Track>("PART_Track", scrollBar); if (track != null) { Thumb thumb = track.Thumb; if (thumb != null) { // At this point, all of the control parts have been found. // Attach to DragStarted to open the tooltip thumb.DragStarted += delegate { var parentGrid = FindControls.FindParent <ExtendedGridControl.ExtendedDataGrid>(source); if (parentGrid != null) { parentGrid.IsVerticalScrolling = true; } if (dataTemplate == null) { return; } ScrollingPreviewData data; if (_previewToolTip == null) { // Create the ToolTip if this is the first time it's been used. _previewToolTip = new ToolTip(); data = new ScrollingPreviewData(); _previewToolTip.Content = data; } else { data = _previewToolTip.Content as ScrollingPreviewData; } // Update the content in the ToolTip if (data != null) { data.UpdateScrollingValues(scrollBar); if (source is ScrollViewer) { parentGrid = FindControls.FindParent <ExtendedGridControl.ExtendedDataGrid>(source); if (parentGrid != null) { data.UpdateItem(parentGrid, vertical); } } else { data.UpdateItem(source as ItemsControl, vertical); } } // Set the Placement and the PlacementTarget _previewToolTip.PlacementTarget = thumb; _previewToolTip.Placement = vertical ? PlacementMode.Left : PlacementMode.Top; _previewToolTip.VerticalOffset = 0.0; _previewToolTip.HorizontalOffset = 0.0; _previewToolTip.ContentTemplate = dataTemplate; _previewToolTip.IsOpen = true; }; // Attach to DragDelta to update the ToolTip's position thumb.DragDelta += delegate { if (dataTemplate == null) { return; } if ((_previewToolTip != null) && // Check that we're within the range of the ScrollBar (scrollBar.Value > scrollBar.Minimum) && (scrollBar.Value < scrollBar.Maximum)) { // This is a little trick to cause the ToolTip to update its position next to the Thumb if (vertical) { _previewToolTip.VerticalOffset = Math.Abs(_previewToolTip.VerticalOffset - 0.0) < Epsilon ? 0.001 : 0.0; } else { _previewToolTip.HorizontalOffset = Math.Abs(_previewToolTip.HorizontalOffset - 0.0) < Epsilon ? 0.001 : 0.0; } } }; // Attach to DragCompleted to close the ToolTip thumb.DragCompleted += delegate { var parentGrid = FindControls.FindParent <ExtendedGridControl.ExtendedDataGrid>(source); if (parentGrid != null) { parentGrid.IsVerticalScrolling = false; } if (dataTemplate == null) { return; } if (_previewToolTip != null) { _previewToolTip.IsOpen = false; } }; // Attach to the Scroll event to update the ToolTip content scrollBar.Scroll += delegate { if (dataTemplate == null) { return; } if (_previewToolTip != null) { // The ScrollBar's value isn't updated quite yet, so // wait until Input priority scrollBar.Dispatcher.BeginInvoke((NoParamCallback) delegate { var data = ( ScrollingPreviewData ) _previewToolTip . Content; data . UpdateScrollingValues (scrollBar); data . UpdateItem (source as ItemsControl, vertical); }, DispatcherPriority.Input); } }; return; } } } // At this point, something wasn't found. If the computed visibility is not visible, // then add a handler to wait for it to become visible. if ((vertical ? scrollViewer.ComputedVerticalScrollBarVisibility : scrollViewer.ComputedHorizontalScrollBarVisibility) != Visibility.Visible) { DependencyPropertyDescriptor propertyDescriptor = DependencyPropertyDescriptor.FromProperty( vertical ? ScrollViewer.ComputedVerticalScrollBarVisibilityProperty : ScrollViewer.ComputedHorizontalScrollBarVisibilityProperty, typeof(ScrollViewer)); if (propertyDescriptor != null) { EventHandler handler = delegate { if (dataTemplate == null) { return; } if ((vertical ? scrollViewer.ComputedVerticalScrollBarVisibility : scrollViewer.ComputedHorizontalScrollBarVisibility) == Visibility.Visible) { EventHandler storedHandler = GetWaitForVisibleScrollBar(source); propertyDescriptor.RemoveValueChanged(scrollViewer, storedHandler); PostAttachToEvents(obj, dataTemplate, vertical); } }; SetWaitForVisibleScrollBar(source, handler); propertyDescriptor.AddValueChanged(scrollViewer, handler); } } } }