123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735 |
- using System;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using System.Windows.Media;
- namespace MediaBrowser.UI.Controls
- {
- /// <summary>
- /// http://www.codeproject.com/Articles/75847/Virtualizing-WrapPanel
- /// Positions child elements in sequential position from left to right, breaking content
- /// to the next line at the edge of the containing box. Subsequent ordering happens
- /// sequentially from top to bottom or from right to left, depending on the value of
- /// the Orientation property.
- /// </summary>
- [DefaultProperty("Orientation")]
- public class VirtualizingWrapPanel : VirtualizingPanel, IScrollInfo
- {
- /// <summary>
- /// Identifies the ItemHeight dependency property.
- /// </summary>
- public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged)));
- /// <summary>
- /// Identifies the Orientation dependency property.
- /// </summary>
- public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(VirtualizingWrapPanel), new PropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged)));
- /// <summary>
- /// Identifies the ItemWidth dependency property.
- /// </summary>
- public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged)));
- /// <summary>
- /// Identifies the ScrollStep dependency property.
- /// </summary>
- public static readonly DependencyProperty ScrollStepProperty = DependencyProperty.Register("ScrollStep", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(10.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged)));
- private bool canHorizontallyScroll;
- private bool canVerticallyScroll;
- private Size contentExtent = new Size(0.0, 0.0);
- private Point contentOffset = default(Point);
- private ScrollViewer scrollOwner;
- private Size viewport = new Size(0.0, 0.0);
- private int previousItemCount;
- /// <summary>
- /// Gets or sets a value that specifies the height of all items that are
- /// contained within a VirtualizingWrapPanel. This is a dependency property.
- /// </summary>
- public double ItemHeight
- {
- get
- {
- return (double)base.GetValue(VirtualizingWrapPanel.ItemHeightProperty);
- }
- set
- {
- base.SetValue(VirtualizingWrapPanel.ItemHeightProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets a value that specifies the width of all items that are
- /// contained within a VirtualizingWrapPanel. This is a dependency property.
- /// </summary>
- public double ItemWidth
- {
- get
- {
- return (double)base.GetValue(VirtualizingWrapPanel.ItemWidthProperty);
- }
- set
- {
- base.SetValue(VirtualizingWrapPanel.ItemWidthProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets a value that specifies the dimension in which child
- /// content is arranged. This is a dependency property.
- /// </summary>
- public Orientation Orientation
- {
- get
- {
- return (Orientation)base.GetValue(VirtualizingWrapPanel.OrientationProperty);
- }
- set
- {
- base.SetValue(VirtualizingWrapPanel.OrientationProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible.
- /// </summary>
- public bool CanHorizontallyScroll
- {
- get
- {
- return this.canHorizontallyScroll;
- }
- set
- {
- if (this.canHorizontallyScroll != value)
- {
- this.canHorizontallyScroll = value;
- base.InvalidateMeasure();
- }
- }
- }
- /// <summary>
- /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible.
- /// </summary>
- public bool CanVerticallyScroll
- {
- get
- {
- return this.canVerticallyScroll;
- }
- set
- {
- if (this.canVerticallyScroll != value)
- {
- this.canVerticallyScroll = value;
- base.InvalidateMeasure();
- }
- }
- }
- /// <summary>
- /// Gets or sets a ScrollViewer element that controls scrolling behavior.
- /// </summary>
- public ScrollViewer ScrollOwner
- {
- get
- {
- return this.scrollOwner;
- }
- set
- {
- this.scrollOwner = value;
- }
- }
- /// <summary>
- /// Gets the vertical offset of the scrolled content.
- /// </summary>
- public double VerticalOffset
- {
- get
- {
- return this.contentOffset.Y;
- }
- }
- /// <summary>
- /// Gets the vertical size of the viewport for this content.
- /// </summary>
- public double ViewportHeight
- {
- get
- {
- return this.viewport.Height;
- }
- }
- /// <summary>
- /// Gets the horizontal size of the viewport for this content.
- /// </summary>
- public double ViewportWidth
- {
- get
- {
- return this.viewport.Width;
- }
- }
- /// <summary>
- /// Gets or sets a value for mouse wheel scroll step.
- /// </summary>
- public double ScrollStep
- {
- get
- {
- return (double)base.GetValue(VirtualizingWrapPanel.ScrollStepProperty);
- }
- set
- {
- base.SetValue(VirtualizingWrapPanel.ScrollStepProperty, value);
- }
- }
- /// <summary>
- /// Gets the vertical size of the extent.
- /// </summary>
- public double ExtentHeight
- {
- get
- {
- return this.contentExtent.Height;
- }
- }
- /// <summary>
- /// Gets the horizontal size of the extent.
- /// </summary>
- public double ExtentWidth
- {
- get
- {
- return this.contentExtent.Width;
- }
- }
- /// <summary>
- /// Gets the horizontal offset of the scrolled content.
- /// </summary>
- public double HorizontalOffset
- {
- get
- {
- return this.contentOffset.X;
- }
- }
- /// <summary>
- /// Scrolls down within content by one logical unit.
- /// </summary>
- public void LineDown()
- {
- this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep);
- }
- /// <summary>
- /// Scrolls left within content by one logical unit.
- /// </summary>
- public void LineLeft()
- {
- this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep);
- }
- /// <summary>
- /// Scrolls right within content by one logical unit.
- /// </summary>
- public void LineRight()
- {
- this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep);
- }
- /// <summary>
- /// Scrolls up within content by one logical unit.
- /// </summary>
- public void LineUp()
- {
- this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep);
- }
- /// <summary>
- /// Forces content to scroll until the coordinate space of a Visual object is visible.
- /// </summary>
- public Rect MakeVisible(Visual visual, Rect rectangle)
- {
- this.MakeVisible(visual as UIElement);
- return rectangle;
- }
- /// <summary>
- /// Scrolls down within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelDown()
- {
- this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep);
- }
- /// <summary>
- /// Scrolls left within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelLeft()
- {
- this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep);
- }
- /// <summary>
- /// Scrolls right within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelRight()
- {
- this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep);
- }
- /// <summary>
- /// Scrolls up within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelUp()
- {
- this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep);
- }
- /// <summary>
- /// Scrolls down within content by one page.
- /// </summary>
- public void PageDown()
- {
- this.SetVerticalOffset(this.VerticalOffset + this.ViewportHeight);
- }
- /// <summary>
- /// Scrolls left within content by one page.
- /// </summary>
- public void PageLeft()
- {
- this.SetHorizontalOffset(this.HorizontalOffset - this.ViewportHeight);
- }
- /// <summary>
- /// Scrolls right within content by one page.
- /// </summary>
- public void PageRight()
- {
- this.SetHorizontalOffset(this.HorizontalOffset + this.ViewportHeight);
- }
- /// <summary>
- /// Scrolls up within content by one page.
- /// </summary>
- public void PageUp()
- {
- this.SetVerticalOffset(this.VerticalOffset - this.viewport.Height);
- }
- /// <summary>
- /// Sets the amount of vertical offset.
- /// </summary>
- public void SetVerticalOffset(double offset)
- {
- if (offset < 0.0 || this.ViewportHeight >= this.ExtentHeight)
- {
- offset = 0.0;
- }
- else
- {
- if (offset + this.ViewportHeight >= this.ExtentHeight)
- {
- offset = this.ExtentHeight - this.ViewportHeight;
- }
- }
- this.contentOffset.Y = offset;
- if (this.ScrollOwner != null)
- {
- this.ScrollOwner.InvalidateScrollInfo();
- }
- base.InvalidateMeasure();
- }
- /// <summary>
- /// Sets the amount of horizontal offset.
- /// </summary>
- public void SetHorizontalOffset(double offset)
- {
- if (offset < 0.0 || this.ViewportWidth >= this.ExtentWidth)
- {
- offset = 0.0;
- }
- else
- {
- if (offset + this.ViewportWidth >= this.ExtentWidth)
- {
- offset = this.ExtentWidth - this.ViewportWidth;
- }
- }
- this.contentOffset.X = offset;
- if (this.ScrollOwner != null)
- {
- this.ScrollOwner.InvalidateScrollInfo();
- }
- base.InvalidateMeasure();
- }
- /// <summary>
- /// Note: Works only for vertical.
- /// </summary>
- internal void PageLast()
- {
- this.contentOffset.Y = this.ExtentHeight;
- if (this.ScrollOwner != null)
- {
- this.ScrollOwner.InvalidateScrollInfo();
- }
- base.InvalidateMeasure();
- }
- /// <summary>
- /// Note: Works only for vertical.
- /// </summary>
- internal void PageFirst()
- {
- this.contentOffset.Y = 0.0;
- if (this.ScrollOwner != null)
- {
- this.ScrollOwner.InvalidateScrollInfo();
- }
- base.InvalidateMeasure();
- }
- /// <summary>
- /// When items are removed, remove the corresponding UI if necessary.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="args"></param>
- protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args)
- {
- switch (args.Action)
- {
- case NotifyCollectionChangedAction.Remove:
- case NotifyCollectionChangedAction.Replace:
- case NotifyCollectionChangedAction.Move:
- base.RemoveInternalChildRange(args.Position.Index, args.ItemUICount);
- return;
- case NotifyCollectionChangedAction.Reset:
- {
- ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
- if (itemsControl != null)
- {
- if (this.previousItemCount != itemsControl.Items.Count)
- {
- if (this.Orientation == Orientation.Horizontal)
- {
- this.SetVerticalOffset(0.0);
- }
- else
- {
- this.SetHorizontalOffset(0.0);
- }
- }
- this.previousItemCount = itemsControl.Items.Count;
- }
- return;
- }
- default:
- return;
- }
- }
- /// <summary>
- /// Measure the children.
- /// </summary>
- /// <param name="availableSize">The available size.</param>
- /// <returns>The desired size.</returns>
- protected override Size MeasureOverride(Size availableSize)
- {
- this.InvalidateScrollInfo(availableSize);
- int firstVisibleIndex;
- int lastVisibleIndex;
- if (this.Orientation == Orientation.Horizontal)
- {
- this.GetVerticalVisibleRange(out firstVisibleIndex, out lastVisibleIndex);
- }
- else
- {
- this.GetHorizontalVisibleRange(out firstVisibleIndex, out lastVisibleIndex);
- }
- UIElementCollection children = base.Children;
- IItemContainerGenerator generator = base.ItemContainerGenerator;
- if (generator != null)
- {
- GeneratorPosition startPos = generator.GeneratorPositionFromIndex(firstVisibleIndex);
- int childIndex = (startPos.Offset == 0) ? startPos.Index : (startPos.Index + 1);
- if (childIndex == -1)
- {
- this.RefreshOffset();
- }
- using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
- {
- int itemIndex = firstVisibleIndex;
- while (itemIndex <= lastVisibleIndex)
- {
- bool newlyRealized;
- UIElement child = generator.GenerateNext(out newlyRealized) as UIElement;
- if (newlyRealized)
- {
- if (childIndex >= children.Count)
- {
- base.AddInternalChild(child);
- }
- else
- {
- base.InsertInternalChild(childIndex, child);
- }
- generator.PrepareItemContainer(child);
- }
- if (child != null)
- {
- child.Measure(new Size(this.ItemWidth, this.ItemHeight));
- }
- itemIndex++;
- childIndex++;
- }
- }
- this.CleanUpChildren(firstVisibleIndex, lastVisibleIndex);
- }
- if (IsCloseTo(availableSize.Height, double.PositiveInfinity) || IsCloseTo(availableSize.Width, double.PositiveInfinity))
- {
- return base.MeasureOverride(availableSize);
- }
- var itemsControl = ItemsControl.GetItemsOwner(this);
- var numItems = itemsControl.Items.Count;
- var width = availableSize.Width;
- var height = availableSize.Height;
- if (Orientation == Orientation.Vertical)
- {
- var numRows = Math.Floor(availableSize.Height / ItemHeight);
- height = numRows * ItemHeight;
- var requiredColumns = Math.Ceiling(numItems / numRows);
- width = Math.Min(requiredColumns * ItemWidth, width);
- }
- else
- {
- var numColumns = Math.Floor(availableSize.Width / ItemWidth);
- width = numColumns * ItemWidth;
- //if (numItems > 0 && numItems < numColumns)
- //{
- // width = Math.Min(numColumns, numItems) * ItemWidth;
- //}
- var requiredRows = Math.Ceiling(numItems / numColumns);
- height = Math.Min(requiredRows * ItemHeight, height);
- }
- return new Size(width, height);
- }
- /// <summary>
- /// Arranges the children.
- /// </summary>
- /// <param name="finalSize">The available size.</param>
- /// <returns>The used size.</returns>
- protected override Size ArrangeOverride(Size finalSize)
- {
- bool isHorizontal = this.Orientation == Orientation.Horizontal;
- this.InvalidateScrollInfo(finalSize);
- int i = 0;
- foreach (object item in base.Children)
- {
- this.ArrangeChild(isHorizontal, finalSize, i++, item as UIElement);
- }
- return finalSize;
- }
- private static void OnAppearancePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- UIElement panel = d as UIElement;
- if (panel != null)
- {
- panel.InvalidateMeasure();
- }
- }
- private void MakeVisible(UIElement element)
- {
- ItemContainerGenerator generator = base.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this);
- if (element != null && generator != null)
- {
- for (int itemIndex = generator.IndexFromContainer(element); itemIndex == -1; itemIndex = generator.IndexFromContainer(element))
- {
- element = element.ParentOfType<UIElement>();
- }
- ScrollViewer scrollViewer = element.ParentOfType<ScrollViewer>();
- if (scrollViewer != null)
- {
- GeneralTransform elementTransform = element.TransformToVisual(scrollViewer);
- Rect elementRectangle = elementTransform.TransformBounds(new Rect(new Point(0.0, 0.0), element.RenderSize));
- if (this.Orientation == Orientation.Horizontal)
- {
- var padding = ItemHeight / 3;
- if (elementRectangle.Bottom > this.ViewportHeight)
- {
- this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Bottom - this.ViewportHeight + padding);
- return;
- }
- if (elementRectangle.Top < 0.0)
- {
- this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Top - padding);
- return;
- }
- }
- else
- {
- var padding = ItemWidth / 3;
- if (elementRectangle.Right > this.ViewportWidth)
- {
- this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Right - this.ViewportWidth + padding);
- return;
- }
- if (elementRectangle.Left < 0.0)
- {
- this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Left - padding);
- }
- }
- }
- }
- }
- private void GetVerticalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex)
- {
- int childrenPerRow = this.GetVerticalChildrenCountPerRow(this.contentExtent);
- firstVisibleItemIndex = (int)Math.Floor(this.VerticalOffset / this.ItemHeight) * childrenPerRow;
- lastVisibleItemIndex = (int)Math.Ceiling((this.VerticalOffset + this.ViewportHeight) / this.ItemHeight) * childrenPerRow - 1;
- this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex);
- }
- private void GetHorizontalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex)
- {
- int childrenPerRow = this.GetHorizontalChildrenCountPerRow(this.contentExtent);
- firstVisibleItemIndex = (int)Math.Floor(this.HorizontalOffset / this.ItemWidth) * childrenPerRow;
- lastVisibleItemIndex = (int)Math.Ceiling((this.HorizontalOffset + this.ViewportWidth) / this.ItemWidth) * childrenPerRow - 1;
- this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex);
- }
- private void AdjustVisibleRange(ref int firstVisibleItemIndex, ref int lastVisibleItemIndex)
- {
- firstVisibleItemIndex--;
- lastVisibleItemIndex++;
- ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
- if (itemsControl != null)
- {
- if (firstVisibleItemIndex < 0)
- {
- firstVisibleItemIndex = 0;
- }
- if (lastVisibleItemIndex >= itemsControl.Items.Count)
- {
- lastVisibleItemIndex = itemsControl.Items.Count - 1;
- }
- }
- }
- private void CleanUpChildren(int minIndex, int maxIndex)
- {
- UIElementCollection children = base.Children;
- IItemContainerGenerator generator = base.ItemContainerGenerator;
- for (int i = children.Count - 1; i >= 0; i--)
- {
- GeneratorPosition pos = new GeneratorPosition(i, 0);
- int itemIndex = generator.IndexFromGeneratorPosition(pos);
- if (itemIndex < minIndex || itemIndex > maxIndex)
- {
- generator.Remove(pos, 1);
- base.RemoveInternalChildRange(i, 1);
- }
- }
- }
- private void ArrangeChild(bool isHorizontal, Size finalSize, int index, UIElement child)
- {
- if (child == null)
- {
- return;
- }
- int count = isHorizontal ? this.GetVerticalChildrenCountPerRow(finalSize) : this.GetHorizontalChildrenCountPerRow(finalSize);
- int itemIndex = base.ItemContainerGenerator.IndexFromGeneratorPosition(new GeneratorPosition(index, 0));
- int row = isHorizontal ? (itemIndex / count) : (itemIndex % count);
- int column = isHorizontal ? (itemIndex % count) : (itemIndex / count);
- Rect rect = new Rect((double)column * this.ItemWidth, (double)row * this.ItemHeight, this.ItemWidth, this.ItemHeight);
- if (isHorizontal)
- {
- rect.Y -= this.VerticalOffset;
- }
- else
- {
- rect.X -= this.HorizontalOffset;
- }
- child.Arrange(rect);
- }
- private void InvalidateScrollInfo(Size availableSize)
- {
- ItemsControl ownerItemsControl = ItemsControl.GetItemsOwner(this);
- if (ownerItemsControl != null)
- {
- Size extent = this.GetExtent(availableSize, ownerItemsControl.Items.Count);
- if (extent != this.contentExtent)
- {
- this.contentExtent = extent;
- this.RefreshOffset();
- }
- if (availableSize != this.viewport)
- {
- this.viewport = availableSize;
- this.InvalidateScrollOwner();
- }
- }
- }
- private void RefreshOffset()
- {
- if (this.Orientation == Orientation.Horizontal)
- {
- this.SetVerticalOffset(this.VerticalOffset);
- return;
- }
- this.SetHorizontalOffset(this.HorizontalOffset);
- }
- private void InvalidateScrollOwner()
- {
- if (this.ScrollOwner != null)
- {
- this.ScrollOwner.InvalidateScrollInfo();
- }
- }
- private Size GetExtent(Size availableSize, int itemCount)
- {
- if (this.Orientation == Orientation.Horizontal)
- {
- int childrenPerRow = this.GetVerticalChildrenCountPerRow(availableSize);
- return new Size((double)childrenPerRow * this.ItemWidth, this.ItemHeight * Math.Ceiling((double)itemCount / (double)childrenPerRow));
- }
- int childrenPerRow2 = this.GetHorizontalChildrenCountPerRow(availableSize);
- return new Size(this.ItemWidth * Math.Ceiling((double)itemCount / (double)childrenPerRow2), (double)childrenPerRow2 * this.ItemHeight);
- }
- private int GetVerticalChildrenCountPerRow(Size availableSize)
- {
- int childrenCountPerRow;
- if (availableSize.Width == double.PositiveInfinity)
- {
- childrenCountPerRow = base.Children.Count;
- }
- else
- {
- childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Width / this.ItemWidth));
- }
- return childrenCountPerRow;
- }
- private int GetHorizontalChildrenCountPerRow(Size availableSize)
- {
- int childrenCountPerRow;
- if (availableSize.Height == double.PositiveInfinity)
- {
- childrenCountPerRow = base.Children.Count;
- }
- else
- {
- childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Height / this.ItemHeight));
- }
- return childrenCountPerRow;
- }
- private static bool IsCloseTo(double value1, double value2)
- {
- return AreClose(value1, value2);
- }
- private static bool AreClose(double value1, double value2)
- {
- if (value1 == value2)
- {
- return true;
- }
- double num = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * 2.2204460492503131E-16;
- double num2 = value1 - value2;
- return -num < num2 && num > num2;
- }
- }
- }
|