private static void OnMinDecimalPlacesChanged(DependencyObject element,
                                                      DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;

            control.InvalidateProperty(DecimalPlacesProperty);
        }
        private static void OnValueChanged(DependencyObject element,
                                           DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;

            if (control.m_text_box != null)
            {
                control.m_text_box.UndoLimit = 0;
                control.m_text_box.UndoLimit = 1;
            }
        }
        private static void OnMajorDeltaChanged(DependencyObject element,
                                                DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;
            float majorDelta           = (float)e.NewValue;

            if (majorDelta < control.MinorDelta)
            {
                control.MinorDelta = majorDelta;
            }
        }
        private static object CoerceDecimalPlaces(DependencyObject element, Object baseValue)
        {
            Int32 decimalPlaces        = (Int32)baseValue;
            NumericUpDownFloat control = (NumericUpDownFloat)element;

            if (decimalPlaces < control.MinDecimalPlaces)
            {
                decimalPlaces = control.MinDecimalPlaces;
            }
            else if (decimalPlaces > control.MaxDecimalPlaces)
            {
                decimalPlaces = control.MaxDecimalPlaces;
            }

            return(decimalPlaces);
        }
        private static void OnMinValueChanged(DependencyObject element,
                                              DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;
            float min_value            = (float)e.NewValue;

            // If minValue steps over MaxValue, shift it
            if (min_value > control.MaxValue)
            {
                control.MaxValue = min_value;
            }

            if (min_value > control.Value)
            {
                control.Value = min_value;
            }
        }
        private static void OnMaxValueChanged(DependencyObject element,
                                              DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;
            float max_value            = (float)e.NewValue;

            // If maxValue steps over MinValue, shift it
            if (max_value < (int)control.MinValue)
            {
                control.MinValue = max_value;
            }

            // max limit of the value
            if (max_value < (int)control.Value)
            {
                control.Value = max_value;
            }
        }
        private static void OnDecimalPlacesChanged(DependencyObject element,
                                                   DependencyPropertyChangedEventArgs e)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;
            Int32 decimalPlaces        = (Int32)e.NewValue;

            control.m_culture.NumberFormat.NumberDecimalDigits = decimalPlaces;

            if (control.IsDecimalPointDynamic)
            {
                control.IsDecimalPointDynamic = false;
                control.InvalidateProperty(ValueProperty);
                control.IsDecimalPointDynamic = true;
            }
            else
            {
                control.InvalidateProperty(ValueProperty);
            }
        }
        private static object CoerceMinDecimalPlaces(DependencyObject element, Object baseValue)
        {
            Int32 minDecimalPlaces     = (Int32)baseValue;
            NumericUpDownFloat control = (NumericUpDownFloat)element;

            if (minDecimalPlaces < 0)
            {
                minDecimalPlaces = 0;
            }
            else if (minDecimalPlaces > 28)
            {
                minDecimalPlaces = 28;
            }
            else if (minDecimalPlaces > control.MaxDecimalPlaces)
            {
                control.MaxDecimalPlaces = minDecimalPlaces;
            }

            return(minDecimalPlaces);
        }
        private static object CoerceValue(DependencyObject element, object baseValue)
        {
            NumericUpDownFloat control = (NumericUpDownFloat)element;
            float value = (float)baseValue;

            control.CoerceValueToBounds(ref value);

            // Get the text representation of Value
            string valueString = value.ToString(m_all_float_digits);

            // Count all decimal places
            int decimalPlaces = control.GetDecimalPlacesCount(valueString);

            if (decimalPlaces > control.DecimalPlaces)
            {
                if (control.IsDecimalPointDynamic)
                {
                    // Assigning DecimalPlaces will coerce the number
                    control.DecimalPlaces = decimalPlaces;

                    // If the specified number of decimal places is still too much
                    if (decimalPlaces > control.DecimalPlaces)
                    {
                        value = control.TruncateValue(valueString, control.DecimalPlaces);
                    }
                }
                else
                {
                    // Remove all overflowing decimal places
                    value = control.TruncateValue(valueString, decimalPlaces);
                }
            }
            else if (control.IsDecimalPointDynamic)
            {
                control.DecimalPlaces = decimalPlaces;
            }

            string new_text;

            if (control.m_text_box != null)
            {
                if (control.IsThousandSeparatorVisible)
                {
                    new_text = value.ToString("N", control.m_culture);
                }
                else
                {
                    new_text = value.ToString("F", control.m_culture);
                }

                // update caret index
                int new_caret_index = new_text.Length - (control.m_text_box.Text.Length - control.m_text_box.CaretIndex);

                if (new_caret_index < 0)
                {
                    new_caret_index = 0;
                }

                if (new_caret_index >= new_text.Length)
                {
                    new_caret_index = new_text.Length - 1;
                }

                // update selection
                int original_decimal_places   = control.GetDecimalPlacesCount(control.m_text_box.Text);
                int new_decimal_places        = control.GetDecimalPlacesCount(new_text);
                int new_selection_start_index = control.m_text_box.SelectionStart;
                int original_selection_length = control.m_text_box.SelectionLength;
                if (control.m_text_box.SelectionLength == 1)
                {
                    new_selection_start_index = control.m_text_box.SelectionStart - (control.m_text_box.Text.Length - original_decimal_places) + (new_text.Length - new_decimal_places);

                    if (new_text.Length < new_selection_start_index + 1)
                    {
                        if (!new_text.Contains(control.m_culture.NumberFormat.NumberDecimalSeparator))
                        {
                            new_selection_start_index += 1;
                            new_text += '.';
                        }

                        new_text += new string('0', new_selection_start_index - new_text.Length + 1);
                    }
                }

                control.m_text_box.Text       = new_text;
                control.m_text_box.CaretIndex = new_caret_index;
                control.m_text_box.Select(new_selection_start_index, original_selection_length);
            }

            return(baseValue);
        }