Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ВАЖНО UpdateSourceTrigger=EXPLICIT
- пришлось использовать ValidationRule если нужен красный бордер на 3,
- просто установить цвет бесполезно - его перекрывает триггер контрола, а делать свой шаблон нах надо
- public class DoubleTextBox : TextBox
- {
- private BindingExpression _be = null!;
- private readonly bool _designMode;
- public DoubleTextBox()
- {
- TextChanged += OnTextChanged;
- DataContextChanged += OnDataContextChanged;
- _designMode = DesignerProperties.GetIsInDesignMode(this);
- }
- private void OnTextChanged(object sender, TextChangedEventArgs e)
- {
- if (!string.IsNullOrWhiteSpace(Text))
- {
- if (Text.EndsWith(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
- {
- if (_be! is { } be)
- {
- be.ValidateWithoutUpdate();
- }
- return;
- }
- if (!IsInputNumeric(Text, CultureInfo.CurrentCulture))
- {
- Text = string.Empty;
- return;
- }
- }
- if (!_designMode)
- _be.UpdateSource();
- }
- [MemberNotNull(nameof(_be))]
- private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
- {
- _be = GetBindingExpression(TextProperty)!;
- }
- #region Overrides of TextBoxBase
- /// <inheritdoc />
- protected override void OnTextInput(TextCompositionEventArgs e)
- {
- var culture = CultureInfo.CurrentCulture;
- if (TryHandleSpecialNonNumericCharacter(e, culture))
- {
- base.OnTextInput(e);
- return;
- }
- // Input is not a special character.
- // Cancel text input if non-numeric.
- e.Handled = !IsInputNumeric(e.Text, culture);
- base.OnTextInput(e);
- }
- private bool IsInputNumeric(string input, IFormatProvider culture) =>
- double.TryParse(input, NumberStyles.Number, culture, out _);
- private bool TryHandleSpecialNonNumericCharacter(TextCompositionEventArgs inputArgs, CultureInfo culture)
- {
- var input = inputArgs.Text;
- switch (input)
- {
- case var _ when input.Equals(culture.NumberFormat.NegativeSign,
- StringComparison.CurrentCultureIgnoreCase):
- case var _ when input.Equals(culture.NumberFormat.PositiveSign,
- StringComparison.CurrentCultureIgnoreCase):
- break;
- // Allow single decimal separator
- case var _ when input.Equals(culture.NumberFormat.NumberDecimalSeparator,
- StringComparison.CurrentCultureIgnoreCase):
- inputArgs.Handled = Text.Contains(culture.NumberFormat.NumberDecimalSeparator);
- break;
- default:
- return false;
- }
- return true;
- }
- #endregion
- }
- --------------------------
- public class FullDoubleNumberhValidationRule : ValidationRule
- {
- private readonly ValidationResult _validResult = new(true, null);
- private readonly ValidationResult _errorResult = new(false, string.Empty);
- public override ValidationResult Validate(object? value, CultureInfo cultureInfo)
- {
- if (value is string text)
- {
- if (text.EndsWith(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
- return _errorResult;
- }
- return _validResult;
- }
- }
- --------------------------
- <controls:DoubleTextBox d:Text="100">
- <controls:DoubleTextBox.Text>
- <Binding
- Converter="{StaticResource SpentConverter}"
- Mode="TwoWay"
- Path="Spent"
- UpdateSourceTrigger="Explicit">
- <Binding.ValidationRules>
- <controls:FullDoubleNumberhValidationRule />
- </Binding.ValidationRules>
- </Binding>
- </controls:DoubleTextBox.Text>
- </controls:DoubleTextBox>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement