/// <inheritdoc />
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!this.initialized)
            {
                this.Initialize();
            }

            var message = this.errorText.ToString();

            if (!(targetType == typeof(ForcePerUnitless) || targetType == typeof(ForcePerUnitless?)))
            {
                message += $"{this.GetType().Name} does not support converting to {targetType.Name}";
            }

            if (message != string.Empty)
            {
                message = message.TrimEnd('\r', '\n');
                if (Is.DesignMode)
                {
                    throw new InvalidOperationException(message);
                }

                return(message);
            }

            if (value == null)
            {
                return(null);
            }

            if (value is double)
            {
                return(new ForcePerUnitless((double)value, this.unit.Value));
            }

            var text = value as string;

            if (string.IsNullOrEmpty(text))
            {
                return(null);
            }

            var unitInput = this.UnitInput ?? Wpf.UnitInput.ScalarOnly;

            switch (unitInput)
            {
            case Wpf.UnitInput.ScalarOnly:
            {
                double d;
                if (double.TryParse(text, NumberStyles.Float, culture, out d))
                {
                    return(new ForcePerUnitless(d, this.unit.Value));
                }

                ForcePerUnitless result;
                if (ForcePerUnitless.TryParse(text, NumberStyles.Float, culture, out result))
                {
                    return($"#{text}#");        // returning modified text so that TypeConverter fails and we get an error
                }

                return(text);        // returning raw to trigger error
            }

            case Wpf.UnitInput.SymbolAllowed:
            {
                double d;
                int    pos = 0;
                WhiteSpaceReader.TryRead(text, ref pos);
                if (DoubleReader.TryRead(text, ref pos, NumberStyles.Float, culture, out d))
                {
                    WhiteSpaceReader.TryRead(text, ref pos);
                    if (pos == text.Length)
                    {
                        return(new ForcePerUnitless(d, this.unit.Value));
                    }
                }

                goto case Wpf.UnitInput.SymbolRequired;
            }

            case Wpf.UnitInput.SymbolRequired:
            {
                ForcePerUnitless result;
                if (ForcePerUnitless.TryParse(text, NumberStyles.Float, culture, out result))
                {
                    return(result);
                }

                return(text);
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
 /// <summary>
 /// Initializes a new instance of <see cref="Gu.Units.Wpf.ForcePerUnitlessExtension"/>.
 /// </summary>
 /// <param name="value"><see cref="Gu.Units.ForcePerUnitless"/>.</param>
 public ForcePerUnitlessExtension(ForcePerUnitless value)
 {
     this.Value = value;
 }
 protected void SetScalarValue(DependencyProperty property, ForcePerUnitless? quantity)
 {
     // we set this flag to prevent from setting scalar value changing quantity values.
     this.isUpdatingScalarValue = true;
     var value = quantity != null
         ? this.Unit.GetScalarValue(quantity.Value)
         : (double?)null;
     this.SetCurrentValue(property, value);
     this.isUpdatingScalarValue = false;
 }
        public override object ReadJson(JsonReader reader, Type objectType, object?existingValue, JsonSerializer serializer)
        {
            var stringValue = (string)reader.Value !;

            return(ForcePerUnitless.Parse(stringValue, serializer.Culture));
        }
 protected virtual void OnMaxValueChanged(ForcePerUnitless? oldValue, ForcePerUnitless? newValue)
 {
     this.SetScalarValue(ScalarMaxValueProperty, newValue);
 }