/// <summary> /// Computes the extent and view port size</summary> /// <param name="pixelMeasuredViewportSize">Available size for the viewport</param> /// <param name="visibleSections">Number of sections to make visible</param> protected void ComputeExtentAndViewport(Size pixelMeasuredViewportSize, int visibleSections) { if (Orientation == Orientation.Horizontal) { m_viewport.Height = visibleSections; m_viewport.Width = pixelMeasuredViewportSize.Width; } else { m_viewport.Width = visibleSections; m_viewport.Height = pixelMeasuredViewportSize.Height; } if (Orientation == Orientation.Horizontal) { m_extent.Height = m_abstractPanel.SectionCount + ViewportHeight - 1; } else { if (m_lastIndexCompletelyVisible) { m_extent.Width = m_abstractPanel.SectionCount; } else { m_extent.Width = m_abstractPanel.SectionCount + 1; } } Debug.WriteLine("Total section count : " + m_abstractPanel.SectionCount); Debug.WriteLine("Visible sections : " + visibleSections.ToString()); Debug.WriteLine("View port width : " + m_viewport.Width.ToString()); Debug.WriteLine("Extend width : " + m_extent.Width.ToString()); Debug.WriteLine("Offset width : " + m_offset.X.ToString()); ScrollOwner?.InvalidateScrollInfo(); }
/// <summary> /// Compares the present sizes (Extent/Viewport) against the local values /// and updates them, if required. /// </summary> /// <param name="extent">The extent of the view.</param> /// <param name="viewportSize">The size of the viewport.</param> private void UpdateMembers(Size extent, Size viewportSize) { if (extent != Extent) { // The Extent of the control has changed. Extent = extent; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } if (viewportSize != Viewport) { // The Viewport of the panel has changed. Viewport = viewportSize; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } // Prevent from getting off to the right if (HorizontalOffset + Viewport.Width + RightOverflowMargin > ExtentWidth) { SetHorizontalOffset(HorizontalOffset + Viewport.Width + RightOverflowMargin); } // Notify UI-subscribers NotifyPropertyChanged("CanScroll"); NotifyPropertyChanged("CanScrollLeft"); NotifyPropertyChanged("CanScrollRight"); }
public void SetHorizontalOffset(double offset) { if (offset < 0 || _viewport.Width >= _extent.Width) { offset = 0; } else { if (offset + _viewport.Width >= _extent.Width) { offset = _extent.Width - _viewport.Width; } } _offset.X = offset; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } _trans.X = -offset; // Force us to realize the correct children InvalidateMeasure(); }
protected override Size ArrangeOverride(Size finalSize) { if (CurrentSession != null) { Content.Invalidate(); foreach (var layer in Layers) { layer.ArrangeViewport(); } if (UpdateScrollInfo) { UpdateScrollInfo = false; ScrollOwner?.InvalidateScrollInfo(); } } if (ForceGarbageCollection) { ForceGarbageCollection = false; GC.Collect(); // continuous gc collect ensures smooth window resizing } return(finalSize); }
// Verifies scrolling data using the passed viewport and extent as newly computed values. // Checks the X/Y offset and coerces them into the range [0, Extent - ViewportSize] // If extent, viewport, or the newly coerced offsets are different than the existing offset, // cachces are updated and InvalidateScrollInfo() is called. private void VerifyScrollData(double viewportWidth, double extentWidth) { bool isValid = true; if (Double.IsInfinity(viewportWidth)) { viewportWidth = extentWidth; } double offsetX = CoerceOffset(ScrollData.OffsetX, extentWidth, viewportWidth); isValid &= DoubleUtil.AreClose(viewportWidth, ScrollData.ViewportWidth); isValid &= DoubleUtil.AreClose(extentWidth, ScrollData.ExtentWidth); isValid &= DoubleUtil.AreClose(ScrollData.OffsetX, offsetX); ScrollData.ViewportWidth = viewportWidth; ScrollData.ExtentWidth = extentWidth; ScrollData.OffsetX = offsetX; if (!isValid) { if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } }
protected virtual void UpdateScrollInfo(Size availableSize, Size extent) { bool invalidateScrollInfo = false; if (extent != Extent) { Extent = extent; invalidateScrollInfo = true; } if (availableSize != Viewport) { Viewport = availableSize; invalidateScrollInfo = true; } if (ViewportHeight != 0 && VerticalOffset != 0 && VerticalOffset + ViewportHeight + 1 >= ExtentHeight) { Offset = new Point(Offset.X, extent.Height - availableSize.Height); invalidateScrollInfo = true; } if (ViewportWidth != 0 && HorizontalOffset != 0 && HorizontalOffset + ViewportWidth + 1 >= ExtentWidth) { Offset = new Point(extent.Width - availableSize.Width, Offset.Y); invalidateScrollInfo = true; } if (invalidateScrollInfo) { ScrollOwner?.InvalidateScrollInfo(); } }
// Verifies scrolling data using the passed viewport and extent as newly computed values. // Checks the X/Y offset and coerces them into the range [0, Extent - ViewportSize] // If extent, viewport, or the newly coerced offsets are different than the existing offset, // cachces are updated and InvalidateScrollInfo() is called. private void VerifyScrollData(Size viewport, Size extent) { Debug.Assert(IsScrollClient); bool fValid = true; // These two lines of code are questionable, but they are needed right now as VSB may return // Infinity size from measure, which is a regression from the old scrolling model. // They also have the incidental affect of probably avoiding reinvalidation at Arrange // when inside a parent that measures you to Infinity. if (Double.IsInfinity(viewport.Width)) { viewport.Width = extent.Width; } if (Double.IsInfinity(viewport.Height)) { viewport.Height = extent.Height; } fValid &= DoubleUtil.AreClose(viewport, _scrollData._viewport); fValid &= DoubleUtil.AreClose(extent, _scrollData._extent); _scrollData._viewport = viewport; _scrollData._extent = extent; fValid &= CoerceOffsets(); if (!fValid) { ScrollOwner.InvalidateScrollInfo(); } }
/// <summary> /// Scrolls left within content by one page. /// </summary> /// <exception cref="System.NotImplementedException"></exception> public void PageLeft() { if (ScrollOwner != null) { SetHorizontalOffset(Math.Max(ScrollOwner.HorizontalOffset - ViewportWidth, 0)); ScrollOwner.InvalidateScrollInfo(); return; } if (_childItems == null) { PopulateInternalChildrenCollection(); } if (_childItems == null) { return; } if (_childItems.Any()) { foreach (var child in _childItems.Where(child => child.ScrollInfo != null)) { SetHorizontalOffset(Math.Max(child.ScrollInfo.HorizontalOffset - ViewportWidth, 0)); break; } } if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
/// <summary> /// Scrolls right within content by one page. /// </summary> /// <exception cref="System.NotImplementedException"></exception> public void PageRight() { if (ScrollOwner != null) { SetHorizontalOffset(Math.Min(ScrollOwner.HorizontalOffset + ViewportWidth, ExtentWidth - ViewportWidth)); ScrollOwner.InvalidateScrollInfo(); return; } if (_childItems == null) { PopulateInternalChildrenCollection(); } if (_childItems == null) { return; } foreach (var child in _childItems) { if (child.ScrollInfo != null) { var newOffset = Math.Min(child.ScrollInfo.HorizontalOffset + ViewportWidth, ExtentWidth - ViewportWidth); child.ScrollInfo.SetHorizontalOffset(newOffset); SetHorizontalOffset(newOffset); break; } } if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
private void UpdateMembers(Size extent, Size viewportSize) { if (extent != Extent) { Extent = extent; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } if (viewportSize != Viewport) { Viewport = viewportSize; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } if (HorizontalOffset + Viewport.Width + RightOverflowMargin > ExtentWidth) { SetHorizontalOffset(HorizontalOffset + Viewport.Width + RightOverflowMargin); } NotifyPropertyChanged("CanScroll"); NotifyPropertyChanged("CanScrollLeft"); NotifyPropertyChanged("CanScrollRight"); }
/// <summary> /// Scrolls left within content by one logical unit. /// </summary> /// <exception cref="System.NotImplementedException"></exception> public void LineLeft() { if (ScrollOwner != null) { SetHorizontalOffset(Math.Max(ScrollOwner.HorizontalOffset - 20, 0)); ScrollOwner.InvalidateScrollInfo(); return; } if (_childItems == null) { PopulateInternalChildrenCollection(); } if (_childItems == null) { return; } foreach (var child in _childItems) { if (child.ScrollInfo != null) { var newOffset = Math.Max(child.ScrollInfo.HorizontalOffset - 20, 0); child.ScrollInfo.SetHorizontalOffset(newOffset); SetHorizontalOffset(newOffset); break; } } if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
/// <summary> /// Verifies the scroll data. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="extent">The extent.</param> protected void VerifyScrollData(Size viewport, Size extent) { bool flag = true; if (double.IsInfinity(viewport.Width)) { viewport.Width = extent.Width; } if (double.IsInfinity(viewport.Height)) { viewport.Height = extent.Height; } flag &= DoubleUtil.AreClose(viewport, _viewport); flag &= DoubleUtil.AreClose(extent, _extent); _viewport = viewport; _extent = extent; if (!(flag & this.CoerceOffsets())) { if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } }
private void UpdateScrollInfo(Size availableSize) { // See how many items there are int itemCount = ItemsOwner.Items.Count; bool viewportChanged = false; bool extentChanged = false; double extent = CalculateExtent(availableSize, itemCount); // Update extent if (extent != ExtentWidth) { ExtentWidth = extent; extentChanged = true; } // Update viewport if (availableSize.Width != ViewportWidth) { ViewportWidth = availableSize.Width; viewportChanged = true; } if ((extentChanged || viewportChanged) && ScrollOwner != null) { HorizontalOffset = CalculateHorizontalOffset(HorizontalOffset); ScrollOwner.InvalidateScrollInfo(); _transform.X = -1 * HorizontalOffset; } }
protected void ComputeExtentAndViewport(Size pixelMeasuredViewportSize) { if (Orientation == Orientation.Horizontal) { m_viewport.Height = 1; m_viewport.Width = pixelMeasuredViewportSize.Width; } else { m_viewport.Width = 1; m_viewport.Height = pixelMeasuredViewportSize.Height; } if (m_abstractPanel == null) { m_extent = new Size(0, 0); } else { if (Orientation == Orientation.Horizontal) { m_extent.Height = m_abstractPanel.SectionCount; } else { m_extent.Width = m_abstractPanel.SectionCount; } } ScrollOwner?.InvalidateScrollInfo(); }
public void SetVerticalOffset(double offset) { if (offset < 0 || _viewport.Height >= _extent.Height) { offset = 0; } else { if (offset + _viewport.Height >= _extent.Height) { offset = _extent.Height - _viewport.Height; } } _offset.Y = offset; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } //_trans.Y = -offset; InvalidateMeasure(); _firstIndex = GetFirstVisibleIndex(); }
/// <summary> /// Computes the extent and viewport size</summary> /// <param name="pixelMeasuredViewportSize">Available size for the viewport</param> /// <param name="visibleSections">Number of sections to make visible</param> protected void ComputeExtentAndViewport(Size pixelMeasuredViewportSize, int visibleSections) { if (Orientation == Orientation.Horizontal) { m_viewport.Height = visibleSections; m_viewport.Width = pixelMeasuredViewportSize.Width; } else { m_viewport.Width = visibleSections; m_viewport.Height = pixelMeasuredViewportSize.Height; } if (Orientation == Orientation.Horizontal) { m_extent.Height = m_abstractPanel.SectionCount + ViewportHeight - 1; } else { m_extent.Width = m_abstractPanel.SectionCount + ViewportWidth - 1; } if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
protected override Size ArrangeOverride(Size finalSize) { var size = base.ArrangeOverride(finalSize); if (ScrollOwner != null) { /*var yOffsetAnimation = new DoubleAnimation() { To = -VerticalOffset, Duration = TimeSpan.FromSeconds(0.2) }; * _transForm.BeginAnimation(TranslateTransform.YProperty, yOffsetAnimation); * * var xOffsetAnimation = new DoubleAnimation() { To = -HorizontalOffset, Duration = TimeSpan.FromSeconds(0.2) }; * _transForm.BeginAnimation(TranslateTransform.XProperty, xOffsetAnimation); * ScrollOwner.InvalidateScrollInfo(); */ DoubleAnimationUsingKeyFrames ydaukf = new DoubleAnimationUsingKeyFrames(); ydaukf.KeyFrames.Add(new LinearDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(0.2d), Value = -VerticalOffset }); _transForm.BeginAnimation(TranslateTransform.YProperty, ydaukf); DoubleAnimationUsingKeyFrames xdaukf = new DoubleAnimationUsingKeyFrames(); xdaukf.KeyFrames.Add(new LinearDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(0.2d), Value = -HorizontalOffset }); _transForm.BeginAnimation(TranslateTransform.XProperty, xdaukf); ScrollOwner.InvalidateScrollInfo(); } return(_screenSize); }
private void MapLoaded(object sender, RoutedEventArgs e) { Loaded -= MapLoaded; loading = false; // Size the map so it is big enough to cover the visible area ViewPort.Size = new Size(ActualWidth, ActualHeight); var desiredZoomLevel = -1; while (ExtentWidth < ViewportWidth || ExtentHeight < ViewportHeight) { desiredZoomLevel++; PanelExtent.Size = Projection.FullMapSizeFor(desiredZoomLevel); } Extent = new Extent { Area = Projection.World, ZoomLevel = desiredZoomLevel }; // for now let's always center it (view port support is comming) SetHorizontalOffset((ExtentWidth - ViewportWidth) / 2); SetVerticalOffset((ExtentHeight - ViewportHeight) / 2); ScrollOwner?.InvalidateScrollInfo(); VisualExtentValuesChanged(this, new PropertyChangedEventArgs(string.Empty)); }
protected override Size ArrangeOverride(Size finalSize) { //foreach(UIElement element in InternalChildren) //{ // element.Arrange(new Rect(new Point(x,y), element.DesiredSize)); // if (Orientation == Orientation.Horizontal) // x += element.DesiredSize.Width; // else // y += element.DesiredSize.Height; //} var size = base.ArrangeOverride(finalSize); if (ScrollOwner != null) { var yOffsetAnimation = new DoubleAnimation() { To = -VerticalOffset, Duration = TimeSpan.FromSeconds(1) }; _transForm.BeginAnimation(TranslateTransform.YProperty, yOffsetAnimation); var xOffsetAnimation = new DoubleAnimation() { To = -HorizontalOffset, Duration = TimeSpan.FromSeconds(1) }; _transForm.BeginAnimation(TranslateTransform.XProperty, xOffsetAnimation); ScrollOwner.InvalidateScrollInfo(); } return(_screenSize); }
/// <summary> /// Measure the control and it's children. /// </summary> protected override Size MeasureOverride(Size constraint) { var infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity); var childSize = base.MeasureOverride(infiniteSize); if (childSize != _unScaledExtent) { // // Use the size of the child as the un-scaled extent content. // _unScaledExtent = childSize; ScrollOwner?.InvalidateScrollInfo(); } // // Update the size of the viewport onto the content based on the passed in 'constraint'. // UpdateViewportSize(constraint); var width = constraint.Width; var height = constraint.Height; if (double.IsInfinity(width)) { width = childSize.Width; } if (double.IsInfinity(height)) { height = childSize.Height; } UpdateTranslationX(); UpdateTranslationY(); return(new Size(width, height)); }
/// <summary> /// This function adjust the current first element index, the current offsets and the current visual children collection to have a valid stack display. /// </summary> private void AdjustOffsetsAndVisualChildren(float desiredNewScrollPosition) { offset = Vector3.Zero; var axis = (int)Orientation; if (ItemVirtualizationEnabled) { UpdateScrollPosition(desiredNewScrollPosition); UpdateAndArrangeVisibleChildren(); } else // no item virtualization { if (elementBounds.Count < 2) // no children { scrollPosition = 0; offset = Vector3.Zero; } else { var viewportSize = Viewport[axis]; var inferiorBound = elementBounds[indexElementMaxScrolling]; var superiorBound = elementBounds[indexElementMaxScrolling + 1]; var boundDifference = superiorBound - inferiorBound; // calculate the maximum scroll position float maxScrollPosition = indexElementMaxScrolling; if (boundDifference > MathUtil.ZeroTolerance) { maxScrollPosition += Math.Min(1 - MathUtil.ZeroTolerance, (extent[axis] - viewportSize - inferiorBound) / boundDifference); } // set a valid scroll position scrollPosition = Math.Max(0, Math.Min(maxScrollPosition, desiredNewScrollPosition)); // add the first element start bound as initial scroll offset var firstElementIndex = (int)Math.Floor(scrollPosition); offset[axis] = -elementBounds[firstElementIndex]; // update the visible element list for hit tests visibleChildren.Clear(); for (var i = firstElementIndex; i < Children.Count; i++) { visibleChildren.Add(Children[i]); if (elementBounds[i + 1] - elementBounds[firstElementIndex + 1] > viewportSize) { break; } } } } // adjust the offset of the children var scrollPositionIndex = (int)Math.Floor(scrollPosition); var scrollPositionRemainder = scrollPosition - scrollPositionIndex; offset[axis] -= scrollPositionRemainder * GetSafeChildSize(scrollPositionIndex, axis); // force the scroll owner to update the scroll info ScrollOwner?.InvalidateScrollInfo(); }
private void ComputeExtentAndViewport(Size pixelMeasuredViewportSize, int visibleSections) { if (Orientation == Orientation.Horizontal) { _viewport.Height = visibleSections; _viewport.Width = pixelMeasuredViewportSize.Width; } else { _viewport.Width = visibleSections; _viewport.Height = pixelMeasuredViewportSize.Height; } if (!(_abstractPanel is null)) { if (Orientation == Orientation.Horizontal) { _extent.Height = _abstractPanel.SectionCount + ViewportHeight - 1; } else { _extent.Width = _abstractPanel.SectionCount + ViewportWidth - 1; } } ScrollOwner?.InvalidateScrollInfo(); }
private void OnScrollChange() { if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
protected override Size ArrangeOverride(Size finalSize) { var ou = this; var size = base.ArrangeOverride(finalSize); if (ScrollOwner != null) { var yOffsetAnimation = new DoubleAnimation() { To = -VerticalOffset, Duration = TimeSpan.FromSeconds(0.1), AccelerationRatio = 0.25, DecelerationRatio = 0.25 , }; _translate.BeginAnimation(TranslateTransform.YProperty, yOffsetAnimation, HandoffBehavior.SnapshotAndReplace); var xOffsetAnimation = new DoubleAnimation() { To = -HorizontalOffset, Duration = TimeSpan.FromSeconds(0.1), AccelerationRatio = 0.25, DecelerationRatio = 0.25 }; _translate.BeginAnimation(TranslateTransform.XProperty, xOffsetAnimation); ScrollOwner.InvalidateScrollInfo(); } ViewPortChanged?.Invoke(_screenSize, _totalSize); return(_screenSize); }
protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Replace: RemoveInternalChildRange(args.Position.Index, args.ItemUICount); break; case NotifyCollectionChangedAction.Move: if (args.Position.Index < 0) { InvalidateMeasure(); ScrollOwner?.InvalidateScrollInfo(); SetVerticalOffset(0); } else { RemoveInternalChildRange(args.OldPosition.Index, args.ItemUICount); } break; case NotifyCollectionChangedAction.Reset: itemsControl = ItemsControl.GetItemsOwner(this); generator = (IRecyclingItemContainerGenerator)ItemContainerGenerator; InvalidateMeasure(); ScrollOwner?.InvalidateScrollInfo(); SetVerticalOffset(0); break; } }
protected void VerifyScrollData(Size viewport, Size extent) { if (double.IsInfinity(viewport.Width)) { viewport.Width = extent.Width; } if (double.IsInfinity(viewport.Height)) { viewport.Height = extent.Height; } _Extent = extent; _Viewport = viewport; _Offset.X = Math.Max(0, Math.Min(_Offset.X, ExtentWidth - ViewportWidth)); _Offset.Y = Math.Max(0, Math.Min(_Offset.Y, ExtentHeight - ViewportHeight)); if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }
// See Ben Constable's series of posts at http://blogs.msdn.com/bencon/ private void UpdateScrollInfo(Size availableSize) { // See how many items there are var itemsControl = ItemsControl.GetItemsOwner(this); var itemCount = itemsControl.HasItems ? itemsControl.Items.Count : 0; var extent = CalculateExtent(availableSize, itemCount); // Update extent if (extent != _extent) { _extent = extent; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } // Update viewport if (availableSize != _viewport) { _viewport = availableSize; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } } }
public void SetHorizontalOffset(double offset) { if (offset < 0 || _viewport.Width >= _extent.Width) { offset = 0; } else { if (offset + _viewport.Width >= _extent.Width) { offset = _extent.Width - _viewport.Width; } } _offset.X = offset; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } InvalidateMeasure(); _firstIndex = GetFirstVisibleIndex(); }
public void SetVerticalOffset(double offset) { if (offset < 0 || _viewport.Height >= _extent.Height) { offset = 0; } else { if (offset + _viewport.Height >= _extent.Height) { offset = _extent.Height - _viewport.Height; } } _offset.Y = offset; if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } _trans.Y = -offset; // Force us to realize the correct children InvalidateMeasure(); }
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs args) { base.OnItemsChanged(args); if (ScrollOwner != null) { ScrollOwner.InvalidateScrollInfo(); } }