/// <summary>
        /// Convert a value.  Called when moving a value from source to target.
        /// </summary>
        /// <param name="values">values as produced by source binding</param>
        /// <param name="targetType">target type</param>
        /// <param name="parameter">converter parameter</param>
        /// <param name="culture">culture information</param>
        /// <returns>
        ///     Converted value.
        ///
        ///     System.Windows.DependencyProperty.UnsetValue may be returned to indicate that
        ///     the converter produced no value and that the fallback (if available)
        ///     or default value should be used instead.
        ///
        ///     Binding.DoNothing may be returned to indicate that the binding
        ///     should not transfer the value or use the fallback or default value.
        /// </returns>
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            //
            // Parameter Validation
            //
            if (parameter == null ||
                values == null ||
                values.Length != 4 ||
                values[0] is not Visibility ||
                values[1] is not double ||
                values[2] is not double ||
                values[3] is not double)
            {
                return(DependencyProperty.UnsetValue);
            }

            if (parameter is not double && parameter is not string)
            {
                return(DependencyProperty.UnsetValue);
            }

            //
            // Conversion
            //

            // If the scroll bar should be visible, then so should our buttons
            Visibility computedVerticalScrollBarVisibility = (Visibility)values[0];

            if (computedVerticalScrollBarVisibility == Visibility.Visible)
            {
                double target;

                if (parameter is string)
                {
                    target = Double.Parse(((string)parameter), NumberFormatInfo.InvariantInfo);
                }
                else
                {
                    target = (double)parameter;
                }

                double verticalOffset = (double)values[1];
                double extentHeight   = (double)values[2];
                double viewportHeight = (double)values[3];

                if (extentHeight != viewportHeight) // Avoid divide by 0
                {
                    // Calculate the percent so that we can see if we are near the edge of the range
                    double percent = Math.Min(100.0, Math.Max(0.0, (verticalOffset * 100.0 / (extentHeight - viewportHeight))));

                    if (DoubleUtil.AreClose(percent, target))
                    {
                        // We are at the end of the range, so no need for this button to be shown
                        return(Visibility.Collapsed);
                    }
                }

                return(Visibility.Visible);
            }

            return(Visibility.Collapsed);
        }
示例#2
0
        /// <summary>
        ///     Parses a DataGridLength from a string given the CultureInfo.
        /// </summary>
        /// <param name="s">String to parse from.</param>
        /// <param name="cultureInfo">Culture Info.</param>
        /// <returns>Newly created DataGridLength instance.</returns>
        /// <remarks>
        /// Formats:
        /// "[value][unit]"
        ///     [value] is a double
        ///     [unit] is a string in DataGridLength._unitTypes connected to a DataGridLengthUnitType
        /// "[value]"
        ///     As above, but the DataGridLengthUnitType is assumed to be DataGridLengthUnitType.Pixel
        /// "[unit]"
        ///     As above, but the value is assumed to be 1.0
        ///     This is only acceptable for a subset of DataGridLengthUnitType: Auto
        /// </remarks>
        private static DataGridLength ConvertFromString(string s, CultureInfo cultureInfo)
        {
            string goodString = s.Trim().ToLowerInvariant();

            // Check if the string matches any of the descriptive unit types.
            // In these cases, there is no need to parse a value.
            for (int i = 0; i < NumDescriptiveUnits; i++)
            {
                string unitString = _unitStrings[i];
                if (goodString == unitString)
                {
                    return(new DataGridLength(1.0, (DataGridLengthUnitType)i));
                }
            }

            double value = 0.0;
            DataGridLengthUnitType unit = DataGridLengthUnitType.Pixel;
            int    strLen     = goodString.Length;
            int    strLenUnit = 0;
            double unitFactor = 1.0;

            // Check if the string contains a non-descriptive unit at the end.
            int numUnitStrings = _unitStrings.Length;

            for (int i = NumDescriptiveUnits; i < numUnitStrings; i++)
            {
                string unitString = _unitStrings[i];

                // Note: This is NOT a culture specific comparison.
                // This is by design: we want the same unit string table to work across all cultures.
                if (goodString.EndsWith(unitString, StringComparison.Ordinal))
                {
                    strLenUnit = unitString.Length;
                    unit       = (DataGridLengthUnitType)i;
                    break;
                }
            }

            // Couldn't match a standard unit type, try a non-standard unit type.
            if (strLenUnit == 0)
            {
                numUnitStrings = _nonStandardUnitStrings.Length;
                for (int i = 0; i < numUnitStrings; i++)
                {
                    string unitString = _nonStandardUnitStrings[i];

                    // Note: This is NOT a culture specific comparison.
                    // This is by design: we want the same unit string table to work across all cultures.
                    if (goodString.EndsWith(unitString, StringComparison.Ordinal))
                    {
                        strLenUnit = unitString.Length;
                        unitFactor = _pixelUnitFactors[i];
                        break;
                    }
                }
            }

            // Check if there is a numerical value to parse
            if (strLen == strLenUnit)
            {
                // There is no numerical value to parse
                if (unit == DataGridLengthUnitType.Star)
                {
                    // Star's value defaults to 1. Anyone else would be 0.
                    value = 1.0;
                }
            }
            else
            {
                // Parse a numerical value
                Debug.Assert(
                    (unit == DataGridLengthUnitType.Pixel) || DoubleUtil.AreClose(unitFactor, 1.0),
                    "unitFactor should not be other than 1.0 unless the unit type is Pixel.");

                string valueString = goodString.Substring(0, strLen - strLenUnit);
                value = Convert.ToDouble(valueString, cultureInfo) * unitFactor;
            }

            return(new DataGridLength(value, unit));
        }
示例#3
0
 /// <summary>
 /// Compares two Vector instances for fuzzy equality.  This function
 /// helps compensate for the fact that double values can
 /// acquire error when operated upon
 /// </summary>
 /// <param name="vector1">The first Vector to compare
 /// <param name="vector2">The second Vector to compare
 /// <returns>Whether or not the two Vector instances are equal</returns>
 public static bool AreClose(System.Windows.Vector vector1, System.Windows.Vector vector2)
 {
     return(DoubleUtil.AreClose(vector1.X, vector2.X) &&
            DoubleUtil.AreClose(vector1.Y, vector2.Y));
 }
示例#4
0
 /// <summary>
 /// Compares two Size instances for fuzzy equality.  This function
 /// helps compensate for the fact that double values can
 /// acquire error when operated upon
 /// </summary>
 /// <param name="size1">The first size to compare
 /// <param name="size2">The second size to compare
 /// <returns>Whether or not the two Size instances are equal</returns>
 public static bool AreClose(Size size1, Size size2)
 {
     return(DoubleUtil.AreClose(size1.Width, size2.Width) &&
            DoubleUtil.AreClose(size1.Height, size2.Height));
 }
示例#5
0
        // The Point, Size, Rect and Matrix class have moved to WinCorLib.  However, we provide
        // internal AreClose methods for our own use here.

        /// <summary>
        /// Compares two points for fuzzy equality.  This function
        /// helps compensate for the fact that double values can
        /// acquire error when operated upon
        /// </summary>
        /// <param name="point1">The first point to compare
        /// <param name="point2">The second point to compare
        /// <returns>Whether or not the two points are equal</returns>
        public static bool AreClose(Point point1, Point point2)
        {
            return(DoubleUtil.AreClose(point1.X, point2.X) &&
                   DoubleUtil.AreClose(point1.Y, point2.Y));
        }
        // Token: 0x06004268 RID: 17000 RVA: 0x001301EC File Offset: 0x0012E3EC
        private static bool AreUniformCorners(CornerRadius borderRadii)
        {
            double topLeft = borderRadii.TopLeft;

            return(DoubleUtil.AreClose(topLeft, borderRadii.TopRight) && DoubleUtil.AreClose(topLeft, borderRadii.BottomLeft) && DoubleUtil.AreClose(topLeft, borderRadii.BottomRight));
        }
示例#7
0
            /// <summary>
            /// OnLayoutUpdated handler. Validates that all participating definitions
            /// have updated min size value. Forces another layout update cycle if needed.
            /// </summary>
            private void OnLayoutUpdated(object sender, EventArgs e)
            {
                double sharedMinSize = 0;

                //  accumulate min size of all participating definitions
                for (int i = 0, count = _registry.Count; i < count; ++i)
                {
                    sharedMinSize = Math.Max(sharedMinSize, _registry[i]._minSize);
                }

                bool sharedMinSizeChanged = !DoubleUtil.AreClose(_minSize, sharedMinSize);

                //  compare accumulated min size with min sizes of the individual definitions
                for (int i = 0, count = _registry.Count; i < count; ++i)
                {
                    DefinitionBase definitionBase = _registry[i];

                    // we'll set d.UseSharedMinimum to maintain the invariant:
                    //      d.UseSharedMinimum iff d._minSize < this.MinSize
                    // i.e. iff d is not a "long-pole" definition.
                    //
                    // Measure/Arrange of d's Grid uses d._minSize for long-pole
                    // definitions, and max(d._minSize, shared size) for
                    // short-pole definitions.  This distinction allows us to react
                    // to changes in "long-pole-ness" more efficiently and correctly,
                    // by avoiding remeasures when a long-pole definition changes.
                    bool useSharedMinimum = !DoubleUtil.AreClose(definitionBase._minSize, sharedMinSize);

                    // before doing that, determine whether d's Grid needs to be remeasured.
                    // It's important _not_ to remeasure if the last measure is still
                    // valid, otherwise infinite loops are possible
                    bool measureIsValid;
                    if (!definitionBase.UseSharedMinimum)
                    {
                        // d was a long-pole.  measure is valid iff it's still a long-pole,
                        // since previous measure didn't use shared size.
                        measureIsValid = !useSharedMinimum;
                    }
                    else if (useSharedMinimum)
                    {
                        // d was a short-pole, and still is.  measure is valid
                        // iff the shared size didn't change
                        measureIsValid = !sharedMinSizeChanged;
                    }
                    else
                    {
                        // d was a short-pole, but is now a long-pole.  This can
                        // happen in several ways:
                        //  a. d's minSize increased to or past the old shared size
                        //  b. other long-pole definitions decreased, leaving
                        //      d as the new winner
                        // In the former case, the measure is valid - it used
                        // d's new larger minSize.  In the latter case, the
                        // measure is invalid - it used the old shared size,
                        // which is larger than d's (possibly changed) minSize
                        measureIsValid = (definitionBase.LayoutWasUpdated &&
                                          DoubleUtil.GreaterThanOrClose(definitionBase._minSize, this.MinSize));
                    }

                    if (!measureIsValid)
                    {
                        Grid parentGrid = (Grid)definitionBase.Parent;
                        parentGrid.InvalidateMeasure();
                    }
                    else if (!DoubleUtil.AreClose(sharedMinSize, definitionBase.SizeCache))
                    {
                        //  if measure is valid then also need to check arrange.
                        //  Note: definitionBase.SizeCache is volatile but at this point
                        //  it contains up-to-date final size
                        Grid parentGrid = (Grid)definitionBase.Parent;
                        parentGrid.InvalidateArrange();
                    }

                    // now we can restore the invariant, and clear the layout flag
                    definitionBase.UseSharedMinimum = useSharedMinimum;
                    definitionBase.LayoutWasUpdated = false;
                }

                _minSize = sharedMinSize;

                _layoutUpdatedHost.LayoutUpdated -= _layoutUpdated;
                _layoutUpdatedHost = null;

                _broadcastInvalidation = true;
            }