public void HitTest_Should_Not_Find_Control_Outside_Scroll_Viewport() { using (TestApplication()) { Border target; Border item1; Border item2; ScrollContentPresenter scroll; Panel container; var root = new TestRoot { Child = container = new Panel { Width = 100, Height = 200, Background = Brushes.Red, Children = { (target = new Border() { Name = "b1", Width = 100, Height = 100, Background = Brushes.Red, }), new Border() { Name = "b2", Width = 100, Height = 100, Background = Brushes.Red, Margin = new Thickness(0, 100, 0, 0), Child = scroll = new ScrollContentPresenter() { CanHorizontallyScroll = true, CanVerticallyScroll = true, Content = new StackPanel() { Children = { (item1 = new Border() { Name = "b3", Width = 100, Height = 100, Background = Brushes.Red, }), (item2 = new Border() { Name = "b4", Width = 100, Height = 100, Background = Brushes.Red, }), } } } } } } }; scroll.UpdateChild(); root.Renderer = new ImmediateRenderer(root); root.Measure(Size.Infinity); root.Arrange(new Rect(container.DesiredSize)); root.Renderer.Paint(new Rect(root.ClientSize)); var result = root.Renderer.HitTest(new Point(50, 150), root, null).First(); Assert.Equal(item1, result); result = root.Renderer.HitTest(new Point(50, 50), root, null).First(); Assert.Equal(target, result); scroll.Offset = new Vector(0, 100); // We don't have LayoutManager set up so do the layout pass manually. scroll.Parent.InvalidateArrange(); container.InvalidateArrange(); container.Arrange(new Rect(container.DesiredSize)); root.Renderer.Paint(new Rect(root.ClientSize)); result = root.Renderer.HitTest(new Point(50, 150), root, null).First(); Assert.Equal(item2, result); result = root.Renderer.HitTest(new Point(50, 50), root, null).First(); Assert.Equal(target, result); } }
private static bool TryScrollToCenterOfView(this ItemsControl itemsControl, object item) { // Find the container var container = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as UIElement; if (container == null) { return(false); } // Find the ScrollContentPresenter ScrollContentPresenter presenter = null; for (Visual vis = container; vis != null && vis != itemsControl; vis = VisualTreeHelper.GetParent(vis) as Visual) { if ((presenter = vis as ScrollContentPresenter) != null) { break; } } if (presenter == null) { return(false); } // Find the IScrollInfo var scrollInfo = !presenter.CanContentScroll ? presenter : presenter.Content as IScrollInfo ?? FirstVisualChild(presenter.Content as ItemsPresenter) as IScrollInfo ?? presenter; // Compute the center point of the container relative to the scrollInfo Size size = container.RenderSize; Point center = container.TransformToAncestor((Visual)scrollInfo).Transform(new Point(size.Width / 2, size.Height / 2)); center.Y += scrollInfo.VerticalOffset; center.X += scrollInfo.HorizontalOffset; // Adjust for logical scrolling if (scrollInfo is StackPanel || scrollInfo is VirtualizingStackPanel) { double logicalCenter = itemsControl.ItemContainerGenerator.IndexFromContainer(container) + 0.5; Orientation orientation = scrollInfo is StackPanel ? ((StackPanel)scrollInfo).Orientation : ((VirtualizingStackPanel)scrollInfo).Orientation; if (orientation == Orientation.Horizontal) { center.X = logicalCenter; } else { center.Y = logicalCenter; } } // Scroll the center of the container to the center of the viewport if (scrollInfo.CanVerticallyScroll) { scrollInfo.SetVerticalOffset(CenteringOffset(center.Y, scrollInfo.ViewportHeight, scrollInfo.ExtentHeight)); } if (scrollInfo.CanHorizontallyScroll) { scrollInfo.SetHorizontalOffset(CenteringOffset(center.X, scrollInfo.ViewportWidth, scrollInfo.ExtentWidth)); } return(true); }
/// <summary> /// Updates FirstItem and LastItem based on the /// Offset and Viewport properties. /// </summary> /// <param name="itemsControl">The ItemsControl that contains the data items.</param> /// <param name="vertical">vertical </param> internal void UpdateItem(ItemsControl itemsControl, bool vertical) { if (itemsControl != null) { int numItems = itemsControl.Items.Count; if (numItems > 0) { if (VirtualizingStackPanel.GetIsVirtualizing(itemsControl)) { // Items scrolling (value == index) var firstIndex = (int)_offset; int lastIndex = (int)_offset + (int)_viewport - 1; if ((firstIndex >= 0) && (firstIndex < numItems)) { FirstItem = itemsControl.Items[firstIndex]; } else { FirstItem = null; } if ((lastIndex >= 0) && (lastIndex < numItems)) { LastItem = itemsControl.Items[lastIndex]; } else { LastItem = null; } } else { // Pixel scrolling (no virtualization) // This will do a linear search through all of the items. // It will assume that the first item encountered that is within view is // the first visible item and the last item encountered that is // within view is the last visible item. // Improvements could be made to this algorithm depending on the // number of items in the collection and the their order relative // to each other on-screen. ScrollContentPresenter scp = null; bool foundFirstItem = false; int bestLastItemIndex = -1; object firstVisibleItem = null; object lastVisibleItem = null; for (int i = 0; i < numItems; i++) { var child = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as UIElement; if (child != null) { if (scp == null) { scp = FindParent <ScrollContentPresenter>(child); if (scp == null) { // Not in a ScrollViewer that we understand return; } } // Transform the origin of the child element to see if it is within view GeneralTransform t = child.TransformToAncestor(scp); Point p = t.Transform(foundFirstItem ? new Point(child.RenderSize.Width, child.RenderSize.Height) : new Point()); if (!foundFirstItem && ((vertical ? p.Y : p.X) >= 0.0)) { // Found the first visible item firstVisibleItem = itemsControl.Items[i]; bestLastItemIndex = i; foundFirstItem = true; } else if (foundFirstItem && ((vertical ? p.Y : p.X) < scp.ActualHeight)) { // Found a candidate for the last visible item bestLastItemIndex = i; } } } if (bestLastItemIndex >= 0) { lastVisibleItem = itemsControl.Items[bestLastItemIndex]; } // Update the item properties FirstItem = firstVisibleItem; LastItem = lastVisibleItem; } } } }
async Task OnDrag(MouseEventArgs e) { var Rect = await GetRect(StartPoint, e.GetPosition(Grid)); if (IsDragging) { Selection.Set(Rect.X, Rect.Y, Rect.Width, Rect.Height); Select(ItemsControl, new Rect(ScrollContentPresenter.TranslatePoint(Selection.TopLeft, ScrollContentPresenter), ScrollContentPresenter.TranslatePoint(Selection.BottomRight, ScrollContentPresenter))); Scroll(e.GetPosition(ItemsControl)); } }
public void GetVisualsAt_Should_Not_Find_Control_Outside_Scroll_Viewport() { using (UnitTestApplication.Start(new TestServices(renderInterface: new MockRenderInterface()))) { Border target; Border item1; Border item2; ScrollContentPresenter scroll; var container = new Panel { Width = 100, Height = 200, Children = new Controls.Controls { (target = new Border() { Width = 100, Height = 100 }), new Border() { Width = 100, Height = 100, Margin = new Thickness(0, 100, 0, 0), Child = scroll = new ScrollContentPresenter() { Content = new StackPanel() { Children = new Controls.Controls { (item1 = new Border() { Width = 100, Height = 100, }), (item2 = new Border() { Width = 100, Height = 100, }), } } } } } }; scroll.UpdateChild(); container.Measure(Size.Infinity); container.Arrange(new Rect(container.DesiredSize)); var context = new DrawingContext(Mock.Of <IDrawingContextImpl>()); context.Render(container); var result = container.GetVisualsAt(new Point(50, 150)).First(); Assert.Equal(item1, result); result = container.GetVisualsAt(new Point(50, 50)).First(); Assert.Equal(target, result); scroll.Offset = new Vector(0, 100); //we don't have setup LayoutManager so we will make it manually scroll.Parent.InvalidateArrange(); container.InvalidateArrange(); container.Arrange(new Rect(container.DesiredSize)); context.Render(container); result = container.GetVisualsAt(new Point(50, 150)).First(); Assert.Equal(item2, result); result = container.GetVisualsAt(new Point(50, 50)).First(); Assert.NotEqual(item1, result); Assert.Equal(target, result); } }
public static void SetLastScrollContentPresenter(DependencyObject target, ScrollContentPresenter value) { target.SetValue(LastScrollContentPresenterProperty, value); }
public override void OnApplyTemplate() { base.OnApplyTemplate(); this.scrollContentPresenter = FindParent <ScrollContentPresenter>(this); }
internal void UpdateItem(ItemsControl itemsControl, bool vertical) { if (itemsControl != null) { int _numItems = itemsControl.Items.Count; if (_numItems > 0) { /* * if (VirtualizingStackPanel.GetIsVirtualizing(itemsControl)) * { * // Items scrolling (value == index) * int _firstIndex = (int) m_offset; * int _lastIndex = (int) m_offset + (int) m_viewport - 1; * * if ((_firstIndex >= 0) && (_firstIndex < _numItems)) * { * FirstItem = itemsControl.Items[_firstIndex]; * } * else * { * FirstItem = null; * } * * if ((_lastIndex >= 0) && (_lastIndex < _numItems)) * { * LastItem = itemsControl.Items[_lastIndex]; * } * else * { * LastItem = null; * } * } * else */ { // Pixel scrolling (no virtualization) // This will do a linear search through all of the items. // It will assume that the first item encountered that is within view is // the first visible item and the last item encountered that is // within view is the last visible item. // Improvements could be made to this algorithm depending on the // number of items in the collection and the their order relative // to each other on-screen. ScrollContentPresenter _scp = null; bool _foundFirstItem = false; int _bestLastItemIndex = -1; object _firstVisibleItem = null; object _lastVisibleItem = null; for (int i = 0; i < _numItems; i++) { UIElement _child = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as UIElement; if (_child != null) { if (_scp == null) { _scp = FindParent <ScrollContentPresenter>(_child); if (_scp == null) { // Not in a ScrollViewer that we understand return; } } // Transform the origin of the child element to see if it is within view GeneralTransform _t = _child.TransformToAncestor(_scp); Point _p = _t.Transform(_foundFirstItem ? new Point(_child.RenderSize.Width, _child.RenderSize.Height) : new Point()); if (!_foundFirstItem && ((vertical ? _p.Y : _p.X) >= 0.0)) { // Found the first visible item _firstVisibleItem = itemsControl.Items[i]; _bestLastItemIndex = i; _foundFirstItem = true; } else if (_foundFirstItem && ((vertical ? _p.Y : _p.X) < _scp.ActualHeight)) { // Found a candidate for the last visible item _bestLastItemIndex = i; } } } if (_bestLastItemIndex >= 0) { _lastVisibleItem = itemsControl.Items[_bestLastItemIndex]; } // Update the item properties FirstItem = _firstVisibleItem; LastItem = _lastVisibleItem; } } } }
static void OnMouseUp(object sender, MouseButtonEventArgs e) { ScrollContentPresenter p = getScrollContentPresenter(sender); if (e.ChangedButton == MouseButton.Left) { if (GetIsDragging(p)) { EndDragging(p); Mouse.Capture(null); UITools.FindAncestor <ListView>(p).Focus(); ListViewItem curSelectedItem = getSelectedItem(p, Mouse.GetPosition(p)); if (curSelectedItem != null && curSelectedItem.Equals(_itemUnderMouse)) { ListView lvControl = UITools.FindAncestor <ListView>(p); ClearSelection(lvControl); _itemUnderMouse.IsSelected = true; } } if (Point.Subtract(GetStartPosition(p), Mouse.GetPosition(p)).Length < 10.0d) { ListView lvControl = UITools.FindAncestor <ListView>(p); ClearSelection(lvControl); } if (_firstSelectedItem != null) { _firstSelectedItem.IsSelected = true; } _firstSelectedItem = null; SetIsDragging(p, false); } else if (e.ChangedButton == MouseButton.Right) { ListView lvControl = UITools.FindAncestor <ListView>(p); ClearSelection(lvControl); if (_itemUnderMouse != null) { _itemUnderMouse.IsSelected = false; } if (_firstSelectedItem != null) { _firstSelectedItem.IsSelected = false; } _firstSelectedItem = null; SetIsDragging(p, false); return; } else { } #endregion #region Data #endregion }
static void UpdateSelection(ScrollContentPresenter p, Rect selectionBounds, bool highlightOnly) { ListView lvControl = UITools.FindAncestor <ListView>(p); if (lvControl != null) { IChildInfo icInfo = UITools.FindVisualChild <Panel>(p) as IChildInfo; List <object> newList = new List <object>(); List <int> newIntList = new List <int>(); if (icInfo != null) { for (int i = 0; i < lvControl.Items.Count; i++) { if (icInfo.GetChildRect(i).IntersectsWith(selectionBounds)) { newList.Add(lvControl.Items[i]); newIntList.Add(i); } } } else //0.4 For GridView, only support selection if drag occur inside the first column if (lvControl.View is GridView) { Point curPos = (Point)PositionCheck(GetSelectionAdorner(p), Mouse.GetPosition(p)); if ((lvControl.View as GridView).Columns.Count > 0) { double col0width = (lvControl.View as GridView).Columns[0].ActualWidth; if (curPos.X < col0width || GetStartPosition(p).X < col0width) { if (_firstSelectedItem == null) { _firstSelectedItem = getSelectedItem(p, curPos); } ListViewItem curSelectedItem = getSelectedItem(p, curPos); if (_firstSelectedItem != null && curSelectedItem != null) { int startIdx = lvControl.ItemContainerGenerator.IndexFromContainer(_firstSelectedItem); int endIdx = lvControl.ItemContainerGenerator.IndexFromContainer(curSelectedItem); for (int i = Math.Min(startIdx, endIdx); i <= Math.Max(startIdx, endIdx); i++) { if (i >= 0) { newList.Add(lvControl.Items[i]); newIntList.Add(i); } } } } } } if (highlightOnly) { SetHighlightCount(lvControl, newIntList.Count); HighlightItems(lvControl, newIntList); } else { SetHighlightCount(lvControl, 0); UnhighlightItems(lvControl); UpdateSelectedItems(lvControl, newList); } } }
static void BeginDragging(ScrollContentPresenter p) { SetStartScrollbarPosition(p, GetScrollbarPosition(p)); SetIsDragging(p, true); }
public static void OnEnableSelectionpChanged(DependencyObject s, DependencyPropertyChangedEventArgs e) { if (s is ListView) { ListView control = s as ListView; var OnScrollChange = (RoutedEventHandler) delegate(object sender, RoutedEventArgs args) { ItemsPresenter ip = UITools.FindVisualChild <ItemsPresenter>(sender as ListView); ScrollContentPresenter p = UITools.FindAncestor <ScrollContentPresenter>(ip); if (GetIsDragging(p) && Mouse.LeftButton == MouseButtonState.Pressed) { UpdatePosition(p, true); } }; var OnMouseDown = (RoutedEventHandler) delegate(object sender, RoutedEventArgs args) { ClearSelection(sender as ListView); }; var OnSizeChanged = (RoutedEventHandler) delegate(object sender, RoutedEventArgs args) { ItemsPresenter ip = UITools.FindVisualChild <ItemsPresenter>(sender as ListView); ScrollContentPresenter p = UITools.FindAncestor <ScrollContentPresenter>(ip); EndDragging(p); }; Action unloadAdorner = () => { ScrollContentPresenter p = GetLastScrollContentPresenter(control); if (p != null) { SelectionAdorner _adorner = GetSelectionAdorner(p); if (AdornerLayer.GetAdornerLayer(p) != null) { AdornerLayer.GetAdornerLayer(p).Remove(_adorner); } control.MouseUp -= new MouseButtonEventHandler(OnMouseUp); control.MouseMove -= new MouseEventHandler(OnMouseMove); _adorner.PreviewMouseDown -= new MouseButtonEventHandler(OnPreviewMouseDown); _adorner.MouseMove -= new MouseEventHandler(OnMouseMove); _adorner.MouseUp -= new MouseButtonEventHandler(OnMouseUp); control.RemoveHandler(ListView.SizeChangedEvent, OnSizeChanged); SetSelectionAdorner(p, null); } }; Action attachAdorner = () => { unloadAdorner(); ItemsPresenter ip = UITools.FindVisualChild <ItemsPresenter>(control); ScrollContentPresenter p = UITools.FindAncestor <ScrollContentPresenter>(ip); if (p != null) { SelectionAdorner _adorner = new SelectionAdorner(p); SetSelectionAdorner(p, _adorner); AdornerLayer.GetAdornerLayer(p).Add(_adorner); control.PreviewMouseDown += new MouseButtonEventHandler(OnPreviewMouseDown); control.MouseUp += new MouseButtonEventHandler(OnMouseUp); control.MouseMove += new MouseEventHandler(OnMouseMove); _adorner.PreviewMouseDown += new MouseButtonEventHandler(OnPreviewMouseDown); _adorner.MouseMove += new MouseEventHandler(OnMouseMove); _adorner.MouseUp += new MouseButtonEventHandler(OnMouseUp); control.AddHandler(ListView.SizeChangedEvent, OnSizeChanged); SetLastScrollContentPresenter(control, p); } }; if ((bool)e.NewValue == true) { if (control.IsLoaded) { attachAdorner(); } else { control.Loaded += delegate { attachAdorner(); } }; control.AddHandler(ScrollViewer.ScrollChangedEvent, OnScrollChange); control.AddHandler(ListView.MouseDownEvent, OnMouseDown); //Monitor view change, and reattach handlers. DependencyPropertyDescriptor viewDescriptor = DependencyPropertyDescriptor.FromProperty(ListView.ViewProperty, typeof(ListView)); viewDescriptor.AddValueChanged (control, delegate { control.Dispatcher.BeginInvoke(DispatcherPriority.Input, attachAdorner); }); } else //If EnableSelection = False { unloadAdorner(); control.RemoveHandler(ScrollViewer.ScrollChangedEvent, OnScrollChange); control.RemoveHandler(ListView.MouseDownEvent, OnMouseDown); SetSelectionAdorner(control, null); } } }
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) { GanttChartView ganttChartView; ScrollViewer scrollViewer; GanttChartItem dataContext = this.Thumb.DataContext as GanttChartItem; if (dataContext != null) { ganttChartView = dataContext.GanttChartView as GanttChartView; if ((ganttChartView != null) && !dataContext.HasChildren) { this.horizontalChange = e.HorizontalChange; scrollViewer = ganttChartView.ScrollViewer; if (!this.isDuringInternalScrollOperation) { double x = this.originalHorizontalPosition + this.horizontalChange; double itemHeight = ganttChartView.ItemHeight; Point p = new Point(x, 0.0); this.isDuringInternalScrollOperation = true; base.Dispatcher.BeginInvoke((Action)(() => { double previousHorizontalOffset = scrollViewer.HorizontalOffset; ScrollContentPresenter visual = ganttChartView.ScrollContentPresenter; if ((scrollViewer != null) && (visual != null)) { try { p = this.TransformToVisual(visual).Transform(p); if (p.X < itemHeight) { scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - itemHeight); } if (p.X > (scrollViewer.ViewportWidth - itemHeight)) { scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + itemHeight); } } catch { } } this.Dispatcher.BeginInvoke((Action)(() => { this.originalHorizontalPosition -= scrollViewer.HorizontalOffset - previousHorizontalOffset; this.isDuringInternalScrollOperation = false; })); })); } switch (this.Role) { case DragTaskThumbRole.UpdateFinish: if (!dataContext.IsMilestone) { double num3 = ganttChartView.GetPosition(dataContext.Finish) + e.HorizontalChange; dataContext.Finish = ganttChartView.GetPreviousVisibleWorkingTime(ganttChartView.GetUpdateScaleTime(ganttChartView.GetDateTime(num3))); return; } return; case DragTaskThumbRole.UpdateCompletedFinish: if (!dataContext.IsMilestone) { double num4 = ganttChartView.GetPosition(dataContext.CompletedFinish) + e.HorizontalChange; dataContext.CompletedFinish = ganttChartView.GetPreviousVisibleWorkingTime(ganttChartView.GetUpdateScaleTime(ganttChartView.GetDateTime(num4))); return; } return; } double position = ganttChartView.GetPosition(dataContext.Start) + e.HorizontalChange; TimeSpan effort = dataContext.Effort; TimeSpan completedEffort = dataContext.CompletedEffort; dataContext.Start = ganttChartView.GetNextVisibleWorkingTime(ganttChartView.GetUpdateScaleTime(ganttChartView.GetDateTime(position))); if (!dataContext.IsMilestone) { dataContext.Effort = effort; dataContext.CompletedEffort = completedEffort; } } } }