Exemple #1
0
        /// <summary>
        /// Applies format and range rules as the text changes.
        /// </summary>
        private void OnTextChanged(object sender, TextChangedEventArgs args)
        {
            // Save selection position relative to right edge
            var originalTextLength = _originalText.Length;
            var selectionOffset    = originalTextLength - _originalSelectionStart;

            // Call before event handler
            var change = new DynamicTextChangedEventArgs(Text, _originalText);

            OnBeforeTextChanged(sender, change);

            // Adjust text value when changed by event handler
            if (Text != change.Text)
            {
                Text = _originalText = change.Text;
            }
            _originalText = Text;

            // Restore selection
            var textLength     = change.Text.Length;
            var selectionStart = textLength - selectionOffset;

            if (selectionStart < 0)
            {
                selectionStart = 0;
            }
            else if (selectionStart > textLength)
            {
                selectionStart = textLength;
            }
            if (SelectionStart != selectionStart)
            {
                SelectionStart = selectionStart;
            }
            _originalSelectionStart = selectionStart;

            // Update cursor
            LayoutCursor();

            // Call after event handlers
            OnAfterTextChanged(sender, change);
        }
Exemple #2
0
        /// <summary>
        /// Called before the base text box changed event is processed but this class, but after the core text box has
        /// already processed a change (because it provides no text change handler itself to override).
        /// This class performs trimming or padding here, so must be called when overridden to retain this functionality.
        /// </summary>
        protected virtual void OnBeforeTextChanged(object sender, DynamicTextChangedEventArgs args)
        {
            // Trim text when too long
            var text      = args.Text;
            var maxLength = MaxLength;

            if (maxLength > 0 && text.Length > maxLength)
            {
                // Trim text
                text = text.Substring(0, maxLength);
            }

            // Pad text when enabled and too short
            var minLength = MinLength;

            if (minLength > 0 && text.Length < MinLength && PadChar.HasValue)
            {
                text = text.PadLeft(minLength, PadChar.Value);
            }

            // Return result
            args.Text = text;
        }
Exemple #3
0
        /// <summary>
        /// Strips non-numeric characters according to <see cref="NumberBase"/> before processing text changes.
        /// </summary>
        protected override void OnBeforeTextChanged(object sender, DynamicTextChangedEventArgs args)
        {
            // Apply decimal sign rules
            var  originalText = args.OriginalText;
            var  textValue    = args.Text;
            bool?sign         = null;

            if (NumberBase == NumericTextBoxNumberBase.Decimal && NumberSigned)
            {
                // Detect sign
                if (textValue.StartsWith("+", StringComparison.OrdinalIgnoreCase))
                {
                    sign = true;
                }
                else if (textValue.StartsWith("-", StringComparison.OrdinalIgnoreCase))
                {
                    sign = false;
                }

                // Apply sign rules
                if (sign.HasValue)
                {
                    // Remove sign when only remaining character
                    if (textValue.Length == 1)
                    {
                        sign = null;
                    }

                    // Prevent selection of sign itself
                    else if (SelectionStart == 0)
                    {
                        SelectionStart = 1;
                    }
                }
            }

            // Strip invalid characters
            var validChars = GetValidNumberChars((int)NumberBase);
            var text       = "";

            foreach (var textChar in args.Text)
            {
                // Allow sign as first char
                if (sign.HasValue && text.Length == 0 && (textChar == '+' || textChar == '-'))
                {
                    text += textChar;
                }
                else
                {
                    // Allow only valid number chars for rest of string
                    if (validChars.IndexOf(textChar.ToString(), StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        // Add valid char with uppercase correction if necessary
                        if (Char.IsLetter(textChar) && !Char.IsUpper(textChar))
                        {
                            // Correct lower to upper case
                            text += Char.ToUpperInvariant(textChar);
                        }
                        else
                        {
                            // No change necessary
                            text += textChar;
                        }
                    }
                    else
                    {
                        // Skip or pad invalid char
                        if (PadChar.HasValue)
                        {
                            text += PadChar.Value;
                        }
                    }
                }
            }

            // Validate number when set (format and sign, minimum and maximum)
            if (!String.IsNullOrEmpty(text))
            {
                var numberBase = (int)NumberBase;
                if (!Number.TryParse(text, numberBase, out Number value) || value < NumberMin || value > NumberMax)
                {
                    // Discard changes when invalid
                    text = originalText;
                }
            }

            // Call base class to trim or pad remaining text
            args.Text = text;
            base.OnBeforeTextChanged(sender, args);
        }
Exemple #4
0
 /// <summary>
 /// Called after the base text box changed event has been processed.
 /// </summary>
 protected virtual void OnAfterTextChanged(object sender, DynamicTextChangedEventArgs args)
 {
 }