Je vyžadována podpora jazyka JavaScript
Některé stránky na tomto webu vyžadují podporu jazyka JavaScript. Váš webový prohlížeč jazyk JavaScript nepodporuje nebo jazyk JavaScript není povolen.
Chcete-li zjistit, zda webový prohlížeč podporuje jazyk JavaScript nebo jazyk JavaScript chcete povolit, přečtěte si nápovědu k vašemu webovému prohlížeči.
ScrollableWrapPanel.cs
Download fileToto je zdrojový kód souboru ScrollableWrapPanel.cs
WrapPanel Silverlight Control with IScrollInfo support.
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.ComponentModel; namespace IMP.Windows.Controls { /// <summary> /// WrapPanel with IScrollInfo support /// </summary> /// <remarks> /// Add <c>VerticalScrollChange</c> and <c>HorizontalScrollChange</c> properties /// </remarks> public partial class ScrollableWrapPanel : WrapPanel, System.Windows.Controls.Primitives.IScrollInfo { #region constants private const double cDefaultVerticalScrollChange = 22.0; private const double cDefaultHorizontalScrollChange = 66.0; #endregion #region member varible and default property initialization private bool m_CanHorizontallyScroll; private bool m_CanVerticallyScroll; private ScrollViewer m_ScrollOwner; private Vector m_Offset; private Size m_Extent; private Size m_Viewport; #endregion #region action methods /// <summary> /// Scrolls up within the content by one logical unit. /// </summary> public virtual void LineUp() { this.SetVerticalOffset(this.VerticalOffset - this.VerticalScrollChange); } /// <summary> /// Scrolls down within the content by one logical unit. /// </summary> public virtual void LineDown() { this.SetVerticalOffset(this.VerticalOffset + this.VerticalScrollChange); } /// <summary> /// Scrolls left within the content by one logical unit. /// </summary> public virtual void LineLeft() { this.SetHorizontalOffset(this.HorizontalOffset - this.HorizontalScrollChange); } /// <summary> /// Scrolls right within the content by one logical unit. /// </summary> public virtual void LineRight() { this.SetHorizontalOffset(this.HorizontalOffset + this.HorizontalScrollChange); } /// <summary> /// Scrolls up within the content after the user clicks the wheel button on a mouse. /// </summary> public virtual void MouseWheelUp() { this.SetVerticalOffset(this.VerticalOffset - (SystemParameters.WheelScrollLines * this.VerticalScrollChange)); } /// <summary> /// Scrolls down within the content after the user clicks the wheel button on a mouse. /// </summary> public virtual void MouseWheelDown() { this.SetVerticalOffset(this.VerticalOffset + (SystemParameters.WheelScrollLines * this.VerticalScrollChange)); } /// <summary> /// Scrolls left within the content after the user clicks the wheel button on a mouse. /// </summary> public virtual void MouseWheelLeft() { this.SetHorizontalOffset(this.HorizontalOffset - (3.0 * this.HorizontalScrollChange)); } /// <summary> /// Scrolls right within the content after the user clicks the wheel button on a mouse. /// </summary> public virtual void MouseWheelRight() { this.SetHorizontalOffset(this.HorizontalOffset + (3.0 * this.HorizontalScrollChange)); } /// <summary> /// Scrolls up within the content by one page. /// </summary> public virtual void PageUp() { this.SetVerticalOffset(this.VerticalOffset - this.ViewportHeight); } /// <summary> /// Scrolls down within the content by one page. /// </summary> public virtual void PageDown() { this.SetVerticalOffset(this.VerticalOffset + this.ViewportHeight); } /// <summary> /// Scrolls left within the content by one page. /// </summary> public virtual void PageLeft() { this.SetHorizontalOffset(this.HorizontalOffset - this.ViewportWidth); } /// <summary> /// Scrolls right within the content by one page. /// </summary> public virtual void PageRight() { this.SetHorizontalOffset(this.HorizontalOffset + this.ViewportWidth); } /// <summary> /// Sets the amount of horizontal offset. /// </summary> /// <param name="offset">The amount that content is horizontally offset from the containing viewport.</param> public void SetHorizontalOffset(double offset) { if (this.CanHorizontallyScroll) { double X = Math.Max(0.0, Math.Min(offset, this.ExtentWidth - this.ViewportWidth)); if (X != m_Offset.X) { m_Offset.X = X; this.InvalidateArrange(); } } } /// <summary> /// Sets the amount of vertical offset. /// </summary> /// <param name="offset">The amount that content is vertically offset from the containing viewport.</param> public void SetVerticalOffset(double offset) { if (this.CanVerticallyScroll) { double Y = Math.Max(0.0, Math.Min(offset, this.ExtentHeight - this.ViewportHeight)); if (Y != m_Offset.Y) { m_Offset.Y = Y; base.InvalidateArrange(); } } } /// <summary> /// Forces content to scroll until the coordinate space of a visual object is visible. /// </summary> /// <param name="visual">A System.Windows.UIElement that becomes visible.</param> /// <param name="rectangle">A bounding rectangle that identifies the coordinate space to make visible.</param> /// <returns>A System.Windows.Rect that is visible.</returns> public Rect MakeVisible(UIElement visual, Rect rectangle) { if (rectangle.IsEmpty || visual == null || visual == this || !IsAncestorOf(visual)) { return Rect.Empty; } Point point = visual.TransformToVisual(this).Transform(new Point(rectangle.X, rectangle.Y)); rectangle.X = point.X; rectangle.Y = point.Y; Rect viewRect = new Rect(this.HorizontalOffset, this.VerticalOffset, this.ViewportWidth, this.ViewportHeight); rectangle.X += viewRect.X; rectangle.Y += viewRect.Y; double X = ComputeScrollOffset(viewRect.Left, viewRect.Right, rectangle.Left, rectangle.Right); double Y = ComputeScrollOffset(viewRect.Top, viewRect.Bottom, rectangle.Top, rectangle.Bottom); this.SetHorizontalOffset(X); this.SetVerticalOffset(Y); viewRect.X = X; viewRect.Y = Y; rectangle.Intersect(viewRect); if (!rectangle.IsEmpty) { rectangle.X -= viewRect.X; rectangle.Y -= viewRect.Y; } return rectangle; } #endregion #region property getters/setters /// <summary> /// VerticalScrollChange dependency property /// </summary> public static readonly DependencyProperty VerticalScrollChangeProperty = DependencyProperty.Register("VerticalScrollChange", typeof(double), typeof(ScrollableWrapPanel), new PropertyMetadata(cDefaultVerticalScrollChange)); /// <summary> /// Vertical Scroll Change /// </summary> [DefaultValue(cDefaultVerticalScrollChange)] public double VerticalScrollChange { get { return (double)base.GetValue(VerticalScrollChangeProperty); } set { base.SetValue(VerticalScrollChangeProperty, value); } } /// <summary> /// HorizontalScrollChange dependency property /// </summary> public static readonly DependencyProperty HorizontalScrollChangeProperty = DependencyProperty.Register("HorizontalScrollChange", typeof(double), typeof(ScrollableWrapPanel), new PropertyMetadata(cDefaultHorizontalScrollChange)); /// <summary> /// Horizontal Scroll Change /// </summary> [DefaultValue(cDefaultHorizontalScrollChange)] public double HorizontalScrollChange { get { return (double)base.GetValue(HorizontalScrollChangeProperty); } set { base.SetValue(HorizontalScrollChangeProperty, value); } } /// <summary> /// Gets the horizontal offset of the scrolled content. /// </summary> public double HorizontalOffset { get { return m_Offset.X; } } /// <summary> /// Gets the vertical offset of the scrolled content. /// </summary> public double VerticalOffset { get { return m_Offset.Y; } } /// <summary> /// Gets the vertical size of the extent. /// </summary> public double ExtentHeight { get { return m_Extent.Height; } } /// <summary> /// Gets the horizontal size of the extent. /// </summary> public double ExtentWidth { get { return m_Extent.Width; } } /// <summary> /// Gets the vertical size of the viewport for this content. /// </summary> public double ViewportHeight { get { return m_Viewport.Height; } } /// <summary> /// Gets the horizontal size of the viewport for this content. /// </summary> public double ViewportWidth { get { return m_Viewport.Width; } } /// <summary> /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible. /// </summary> public bool CanHorizontallyScroll { get { return m_CanHorizontallyScroll; } set { m_CanHorizontallyScroll = value; } } /// <summary> /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible. /// </summary> public bool CanVerticallyScroll { get { return m_CanVerticallyScroll; } set { m_CanVerticallyScroll = value; } } /// <summary> /// Gets or sets a System.Windows.Controls.ScrollViewer element that controls scrolling behavior. /// </summary> public ScrollViewer ScrollOwner { get { return m_ScrollOwner; } set { m_ScrollOwner = value; } } #endregion #region override methods /// <summary> /// Overrides MeasureOverride /// </summary> protected override Size MeasureOverride(Size constraint) { var desiredSize = base.MeasureOverride(constraint); this.VerifyScrollData(constraint, desiredSize); return desiredSize; } /// <summary> /// Overrides ArrangeOverride /// </summary> protected override Size ArrangeOverride(Size arrangeSize) { var size = base.ArrangeOverride(arrangeSize); for (int i = 0; i < Children.Count; i++) { UIElement element = Children[i]; Size desiredSize = element.DesiredSize; var gt = element.TransformToVisual(this); var pos = gt.Transform(new Point(0, 0)); var finalRect = new Rect(pos.X - m_Offset.X, pos.Y - m_Offset.Y, desiredSize.Width, desiredSize.Height); element.Arrange(finalRect); } return size; } #endregion #region private member functions private void VerifyScrollData(Size viewport, Size extent) { m_Viewport = viewport; m_Extent = extent; if (m_Offset.X > (m_Extent.Width - m_Viewport.Width)) { m_Offset.X = m_Extent.Width - m_Viewport.Width; } if (m_Offset.X < 0.0) { m_Offset.X = 0.0; } if (m_Offset.Y > (m_Extent.Height - m_Viewport.Height)) { m_Offset.Y = m_Extent.Height - m_Viewport.Height; } if (m_Offset.Y < 0.0) { m_Offset.Y = 0.0; } if (this.ScrollOwner != null) { this.ScrollOwner.InvalidateScrollInfo(); } } private bool IsAncestorOf(UIElement element) { UIElement panel = this; UIElement reference = element; while (reference != null && reference != panel) { reference = VisualTreeHelper.GetParent(reference) as UIElement; } return reference == panel; } private static double ComputeScrollOffset(double topView, double bottomView, double topChild, double bottomChild) { bool offBottom = topChild < topView && bottomChild < bottomView; bool offTop = bottomChild > bottomView && topChild > topView; bool tooLarge = (bottomChild - topChild) > (bottomView - topView); if (!offBottom && !offTop) { //Don't do anything, already in view return topView; } if ((offBottom && !tooLarge) || (offTop && tooLarge)) { return topChild; } return (bottomChild - (bottomView - topView)); } #endregion } }