月更
This commit is contained in:
81
AntDesignWPF/Utils/CornerRadiusUtil.cs
Normal file
81
AntDesignWPF/Utils/CornerRadiusUtil.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System.Windows;
|
||||
|
||||
public static class CornerRadiusUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证角半径是否只包含有效值
|
||||
/// 有效性检查集作为参数传递。
|
||||
/// </summary>
|
||||
/// <param name='corner'>CornerRadius value</param>
|
||||
/// <param name='allowNegative'>allows negative values</param>
|
||||
/// <param name='allowNaN'>allows Double.NaN</param>
|
||||
/// <param name='allowPositiveInfinity'>allows Double.PositiveInfinity</param>
|
||||
/// <param name='allowNegativeInfinity'>allows Double.NegativeInfinity</param>
|
||||
/// <returns>Whether or not the CornerRadius complies to the range specified</returns>
|
||||
public static bool IsValid(CornerRadius corner, bool allowNegative, bool allowNaN, bool allowPositiveInfinity, bool allowNegativeInfinity)
|
||||
{
|
||||
if (!allowNegative)
|
||||
{
|
||||
if (corner.TopLeft < 0d || corner.TopRight < 0d || corner.BottomLeft < 0d || corner.BottomRight < 0d)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowNaN)
|
||||
{
|
||||
if (DoubleUtil.IsNaN(corner.TopLeft) || DoubleUtil.IsNaN(corner.TopRight) ||
|
||||
DoubleUtil.IsNaN(corner.BottomLeft) || DoubleUtil.IsNaN(corner.BottomRight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowPositiveInfinity)
|
||||
{
|
||||
if (double.IsPositiveInfinity(corner.TopLeft) || double.IsPositiveInfinity(corner.TopRight) ||
|
||||
double.IsPositiveInfinity(corner.BottomLeft) || double.IsPositiveInfinity(corner.BottomRight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowNegativeInfinity)
|
||||
{
|
||||
if (double.IsNegativeInfinity(corner.TopLeft) || double.IsNegativeInfinity(corner.TopRight) ||
|
||||
double.IsNegativeInfinity(corner.BottomLeft) || double.IsNegativeInfinity(corner.BottomRight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if the CornerRadius contains only zero values
|
||||
/// </summary>
|
||||
/// <param name="corner">CornerRadius</param>
|
||||
/// <returns>Size</returns>
|
||||
public static bool IsZero(CornerRadius corner)
|
||||
{
|
||||
return DoubleUtil.IsZero(corner.TopLeft) && DoubleUtil.IsZero(corner.TopRight)
|
||||
&& DoubleUtil.IsZero(corner.BottomRight) && DoubleUtil.IsZero(corner.BottomLeft);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if the CornerRadius contains same values
|
||||
/// </summary>
|
||||
/// <param name="corner">CornerRadius</param>
|
||||
/// <returns>true if yes, otherwise false</returns>
|
||||
public static bool IsUniform(CornerRadius corner)
|
||||
{
|
||||
var topLeft = corner.TopLeft;
|
||||
return DoubleUtil.AreClose(topLeft, corner.TopRight)
|
||||
&& DoubleUtil.AreClose(topLeft, corner.BottomRight)
|
||||
&& DoubleUtil.AreClose(topLeft, corner.BottomLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
135
AntDesignWPF/Utils/DoubleUtil.cs
Normal file
135
AntDesignWPF/Utils/DoubleUtil.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal static class DoubleUtil
|
||||
{
|
||||
// Const values
|
||||
// Smallest double value such that 1.0+DBL_EPSILON != 1.0
|
||||
internal const double DBL_EPSILON = 2.2204460492503131e-016;
|
||||
|
||||
// Number close to zero, where float.MinValue is -float.MaxValue
|
||||
internal const float FLT_MIN = 1.175494351e-38F;
|
||||
|
||||
/// <summary>
|
||||
/// AreClose - Returns whether or not two doubles are "close". That is, whether or
|
||||
/// not they are within epsilon of each other. Note that this epsilon is proportional
|
||||
/// to the numbers themselves to that AreClose survives scalar multiplication.
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
||||
/// returns false. This is important enough to repeat:
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
||||
/// used for optimizations *only*.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - the result of the AreClose comparision.
|
||||
/// </returns>
|
||||
/// <param name="value1"> The first double to compare. </param>
|
||||
/// <param name="value2"> The second double to compare. </param>
|
||||
public static bool AreClose(double value1, double value2)
|
||||
{
|
||||
//in case they are Infinities (then epsilon check does not work)
|
||||
if (value1 == value2) return true;
|
||||
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
|
||||
var eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
|
||||
var delta = value1 - value2;
|
||||
return -eps < delta && eps > delta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LessThan - Returns whether or not the first double is less than the second double.
|
||||
/// That is, whether or not the first is strictly less than *and* not within epsilon of
|
||||
/// the other number. Note that this epsilon is proportional to the numbers themselves
|
||||
/// to that AreClose survives scalar multiplication. Note,
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
||||
/// returns false. This is important enough to repeat:
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
||||
/// used for optimizations *only*.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - the result of the LessThan comparision.
|
||||
/// </returns>
|
||||
/// <param name="value1"> The first double to compare. </param>
|
||||
/// <param name="value2"> The second double to compare. </param>
|
||||
public static bool LessThan(double value1, double value2)
|
||||
{
|
||||
return value1 < value2 && !AreClose(value1, value2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GreaterThan - Returns whether or not the first double is greater than the second double.
|
||||
/// That is, whether or not the first is strictly greater than *and* not within epsilon of
|
||||
/// the other number. Note that this epsilon is proportional to the numbers themselves
|
||||
/// to that AreClose survives scalar multiplication. Note,
|
||||
/// There are plenty of ways for this to return false even for numbers which
|
||||
/// are theoretically identical, so no code calling this should fail to work if this
|
||||
/// returns false. This is important enough to repeat:
|
||||
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
|
||||
/// used for optimizations *only*.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - the result of the GreaterThan comparision.
|
||||
/// </returns>
|
||||
/// <param name="value1"> The first double to compare. </param>
|
||||
/// <param name="value2"> The second double to compare. </param>
|
||||
public static bool GreaterThan(double value1, double value2)
|
||||
{
|
||||
return value1 > value2 && !AreClose(value1, value2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IsOne - Returns whether or not the double is "close" to 1. Same as AreClose(double, 1),
|
||||
/// but this is faster.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - the result of the AreClose comparision.
|
||||
/// </returns>
|
||||
/// <param name="value"> The double to compare to 1. </param>
|
||||
public static bool IsOne(double value)
|
||||
{
|
||||
return Math.Abs(value - 1.0) < 10.0 * DBL_EPSILON;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IsZero - Returns whether or not the double is "close" to 0. Same as AreClose(double, 0),
|
||||
/// but this is faster.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// bool - the result of the AreClose comparision.
|
||||
/// </returns>
|
||||
/// <param name="value"> The double to compare to 0. </param>
|
||||
public static bool IsZero(double value)
|
||||
{
|
||||
return Math.Abs(value) < 10.0 * DBL_EPSILON;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
private struct NanUnion
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal double DoubleValue;
|
||||
[FieldOffset(0)]
|
||||
internal ulong UintValue;
|
||||
}
|
||||
|
||||
// The standard CLR double.IsNaN() function is approximately 100 times slower than our own wrapper,
|
||||
// so please make sure to use DoubleUtil.IsNaN() in performance sensitive code.
|
||||
// PS item that tracks the CLR improvement is DevDiv Schedule : 26916.
|
||||
// IEEE 754 : If the argument is any value in the range 0x7ff0000000000001L through 0x7fffffffffffffffL
|
||||
// or in the range 0xfff0000000000001L through 0xffffffffffffffffL, the result will be NaN.
|
||||
public static bool IsNaN(double value)
|
||||
{
|
||||
var t = new NanUnion
|
||||
{
|
||||
DoubleValue = value
|
||||
};
|
||||
|
||||
var exp = t.UintValue & 0xfff0000000000000;
|
||||
var man = t.UintValue & 0x000fffffffffffff;
|
||||
|
||||
return (exp == 0x7ff0000000000000 || exp == 0xfff0000000000000) && man != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
AntDesignWPF/Utils/DpiUtil.cs
Normal file
78
AntDesignWPF/Utils/DpiUtil.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
public static class DpiUtil
|
||||
{
|
||||
public static DpiScale GetDpi(Visual visual)
|
||||
{
|
||||
#if NET40 || NET45
|
||||
var source = PresentationSource.FromVisual(visual);
|
||||
|
||||
if (source?.CompositionTarget == null)
|
||||
{
|
||||
return new DpiScale(1.0, 1.0);
|
||||
}
|
||||
|
||||
var device = source.CompositionTarget.TransformToDevice;
|
||||
return new DpiScale(device.M11, device.M22);
|
||||
#else
|
||||
return VisualTreeHelper.GetDpi(visual);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if NET40 || NET45
|
||||
/// <summary>Stores DPI information from which a <see cref="T:System.Windows.Media.Visual" /> or <see cref="T:System.Windows.UIElement" /> is rendered.</summary>
|
||||
public struct DpiScale
|
||||
{
|
||||
/// <summary>Gets the DPI scale on the X axis.</summary>
|
||||
/// <returns>The DPI scale for the X axis.</returns>
|
||||
public double DpiScaleX { get; private set; }
|
||||
|
||||
/// <summary>Gets the DPI scale on the Yaxis.</summary>
|
||||
/// <returns>The DPI scale for the Y axis.</returns>
|
||||
public double DpiScaleY { get; private set; }
|
||||
|
||||
/// <summary>Get or sets the PixelsPerDip at which the text should be rendered.</summary>
|
||||
/// <returns>The current <see cref="P:System.Windows.DpiScale.PixelsPerDip" /> value.</returns>
|
||||
public double PixelsPerDip
|
||||
{
|
||||
get
|
||||
{
|
||||
return DpiScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the DPI along X axis.</summary>
|
||||
/// <returns>The DPI along the X axis.</returns>
|
||||
public double PixelsPerInchX
|
||||
{
|
||||
get
|
||||
{
|
||||
return 96.0 * DpiScaleX;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the DPI along Y axis.</summary>
|
||||
/// <returns>The DPI along the Y axis.</returns>
|
||||
public double PixelsPerInchY
|
||||
{
|
||||
get
|
||||
{
|
||||
return 96.0 * DpiScaleY;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="T:System.Windows.DpiScale" /> structure.</summary>
|
||||
/// <param name="dpiScaleX">The DPI scale on the X axis.</param>
|
||||
/// <param name="dpiScaleY">The DPI scale on the Y axis. </param>
|
||||
public DpiScale(double dpiScaleX, double dpiScaleY)
|
||||
{
|
||||
DpiScaleX = dpiScaleX;
|
||||
DpiScaleY = dpiScaleY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
34
AntDesignWPF/Utils/RectUtil.cs
Normal file
34
AntDesignWPF/Utils/RectUtil.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
internal static class RectUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Deflates rectangle by given thickness
|
||||
/// </summary>
|
||||
/// <param name="rect">Rectangle</param>
|
||||
/// <param name="thick">Thickness</param>
|
||||
/// <returns>Deflated Rectangle</returns>
|
||||
public static Rect Deflate(Rect rect, Thickness thick)
|
||||
{
|
||||
return new Rect(rect.Left + thick.Left, rect.Top + thick.Top,
|
||||
Math.Max(0.0, rect.Width - thick.Left - thick.Right),
|
||||
Math.Max(0.0, rect.Height - thick.Top - thick.Bottom));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inflates rectangle by given thickness
|
||||
/// </summary>
|
||||
/// <param name="rect">Rectangle</param>
|
||||
/// <param name="thick">Thickness</param>
|
||||
/// <returns>Inflated Rectangle</returns>
|
||||
public static Rect Inflate(Rect rect, Thickness thick)
|
||||
{
|
||||
return new Rect(rect.Left - thick.Left, rect.Top - thick.Top,
|
||||
Math.Max(0.0, rect.Width + thick.Left + thick.Right),
|
||||
Math.Max(0.0, rect.Height + thick.Top + thick.Bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
94
AntDesignWPF/Utils/Spinner.cs
Normal file
94
AntDesignWPF/Utils/Spinner.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using AntDesign.WPF.Contracts;
|
||||
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to spin for controls.
|
||||
/// Known defects:
|
||||
/// Using trigger to change control RenderTransform property will result in animation lose.
|
||||
/// Try adding the Spin property Setter after the RenderTransform property Setter for notification purposes.
|
||||
/// Example: Theme/Switch.xaml
|
||||
/// </summary>
|
||||
public static class Spinner
|
||||
{
|
||||
private const string storyBoardName = "AntDesign.WPF.SpinnerStoryBoard";
|
||||
|
||||
/// <summary>
|
||||
/// Start the spinning animation.
|
||||
/// </summary>
|
||||
public static void BeginSpin<T>(this T control, double seconds) where T : FrameworkElement, ISpinable
|
||||
{
|
||||
var transform = control.RenderTransform;
|
||||
control.SetCurrentValue(UIElement.RenderTransformOriginProperty, new Point(0.5, 0.5));
|
||||
TransformGroup transformGroup;
|
||||
|
||||
if (transform is TransformGroup)
|
||||
{
|
||||
if (!(((TransformGroup)transform).Children.FirstOrDefault() is RotateTransform))
|
||||
{
|
||||
transformGroup = (TransformGroup)transform.Clone();
|
||||
transformGroup.Children.Insert(0, new RotateTransform(0.0));
|
||||
control.SetCurrentValue(UIElement.RenderTransformProperty, transformGroup);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
transformGroup = new TransformGroup();
|
||||
|
||||
if (transform is RotateTransform)
|
||||
{
|
||||
transformGroup.Children.Add(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
transformGroup.Children.Add(new RotateTransform(0.0));
|
||||
|
||||
if (transform != null && transform != Transform.Identity)
|
||||
{
|
||||
transformGroup.Children.Add(transform);
|
||||
}
|
||||
}
|
||||
|
||||
control.SetCurrentValue(UIElement.RenderTransformProperty, transformGroup);
|
||||
}
|
||||
|
||||
if (!(control.Resources[storyBoardName] is Storyboard storyboard))
|
||||
{
|
||||
storyboard = new Storyboard();
|
||||
var animation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 360,
|
||||
AutoReverse = false,
|
||||
Duration = TimeSpan.FromSeconds(seconds),
|
||||
RepeatBehavior = RepeatBehavior.Forever
|
||||
};
|
||||
|
||||
Storyboard.SetTarget(animation, control);
|
||||
Storyboard.SetTargetProperty(animation,
|
||||
new PropertyPath("(0).(1)[0].(2)", UIElement.RenderTransformProperty,
|
||||
TransformGroup.ChildrenProperty, RotateTransform.AngleProperty));
|
||||
|
||||
storyboard.Children.Add(animation);
|
||||
control.Resources.Add(storyBoardName, storyboard);
|
||||
}
|
||||
|
||||
storyboard.Begin();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the spinning animation.
|
||||
/// </summary>
|
||||
public static void StopSpin<T>(this T control) where T : FrameworkElement, ISpinable
|
||||
{
|
||||
(control.Resources[storyBoardName] as Storyboard)?.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
87
AntDesignWPF/Utils/ThicknessUtil.cs
Normal file
87
AntDesignWPF/Utils/ThicknessUtil.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System.Windows;
|
||||
|
||||
internal static class ThicknessUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies if this Thickness contains only valid values
|
||||
/// The set of validity checks is passed as parameters.
|
||||
/// </summary>
|
||||
/// <param name='thick'>Thickness value</param>
|
||||
/// <param name='allowNegative'>allows negative values</param>
|
||||
/// <param name='allowNaN'>allows Double.NaN</param>
|
||||
/// <param name='allowPositiveInfinity'>allows Double.PositiveInfinity</param>
|
||||
/// <param name='allowNegativeInfinity'>allows Double.NegativeInfinity</param>
|
||||
/// <returns>Whether or not the thickness complies to the range specified</returns>
|
||||
public static bool IsValid(Thickness thick, bool allowNegative, bool allowNaN, bool allowPositiveInfinity, bool allowNegativeInfinity)
|
||||
{
|
||||
if (!allowNegative)
|
||||
{
|
||||
if (thick.Left < 0d || thick.Right < 0d || thick.Top < 0d || thick.Bottom < 0d)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allowNaN)
|
||||
{
|
||||
if (DoubleUtil.IsNaN(thick.Left) || DoubleUtil.IsNaN(thick.Right)
|
||||
|| DoubleUtil.IsNaN(thick.Top) || DoubleUtil.IsNaN(thick.Bottom))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allowPositiveInfinity)
|
||||
{
|
||||
if (double.IsPositiveInfinity(thick.Left) || double.IsPositiveInfinity(thick.Right)
|
||||
|| double.IsPositiveInfinity(thick.Top) || double.IsPositiveInfinity(thick.Bottom))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowNegativeInfinity)
|
||||
{
|
||||
if (double.IsNegativeInfinity(thick.Left) || double.IsNegativeInfinity(thick.Right)
|
||||
|| double.IsNegativeInfinity(thick.Top) || double.IsNegativeInfinity(thick.Bottom))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to add up the left and right size as width, as well as the top and bottom size as height
|
||||
/// </summary>
|
||||
/// <param name="thick">Thickness</param>
|
||||
/// <returns>Size</returns>
|
||||
public static Size CollapseThickness(Thickness thick)
|
||||
{
|
||||
return new Size(thick.Left + thick.Right, thick.Top + thick.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if the Thickness contains only zero values
|
||||
/// </summary>
|
||||
/// <param name="thick">Thickness</param>
|
||||
/// <returns>Size</returns>
|
||||
public static bool IsZero(Thickness thick)
|
||||
{
|
||||
return DoubleUtil.IsZero(thick.Left) && DoubleUtil.IsZero(thick.Top)
|
||||
&& DoubleUtil.IsZero(thick.Right) && DoubleUtil.IsZero(thick.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if all the values in Thickness are same
|
||||
/// </summary>
|
||||
/// <param name="thick">Thickness</param>
|
||||
/// <returns>true if yes, otherwise false</returns>
|
||||
public static bool IsUniform(Thickness thick)
|
||||
{
|
||||
var left = thick.Left;
|
||||
return DoubleUtil.AreClose(left, thick.Top)
|
||||
&& DoubleUtil.AreClose(left, thick.Right)
|
||||
&& DoubleUtil.AreClose(left, thick.Bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
AntDesignWPF/Utils/UIElementUtil.cs
Normal file
31
AntDesignWPF/Utils/UIElementUtil.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace AntDesign.WPF.Utils
|
||||
{
|
||||
using System;
|
||||
|
||||
public static class UIElementUtil
|
||||
{
|
||||
public static double RoundLayoutValue(double value, double dpiScale)
|
||||
{
|
||||
double newValue;
|
||||
|
||||
// If DPI == 1, don't use DPI-aware rounding.
|
||||
if (!DoubleUtil.AreClose(dpiScale, 1.0))
|
||||
{
|
||||
newValue = Math.Round(value * dpiScale) / dpiScale;
|
||||
// If rounding produces a value unacceptable to layout (NaN, Infinity or MaxValue), use the original value.
|
||||
if (double.IsNaN(newValue) ||
|
||||
double.IsInfinity(newValue) ||
|
||||
DoubleUtil.AreClose(newValue, double.MaxValue))
|
||||
{
|
||||
newValue = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = Math.Round(value);
|
||||
}
|
||||
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user