I want validate textbox IN WPF MVVM pattern server side to allow number with decimal value, like
1O.10
10.01
2.22
3.444
1234.676
but not alphanumerics like
FHFJ
XTHKX
SPECIAL CHARATER(@#$$)
67..8787
This my code snippet


I want validate textbox IN WPF MVVM pattern server side to allow number with decimal value, like
1O.10
10.01
2.22
3.444
1234.676
but not alphanumerics like
FHFJ
XTHKX
SPECIAL CHARATER(@#$$)
67..8787
This my code snippet


A View Model based solution may look as following:
    double _MyValidNumber;
    string _MyNumber;
    public string MyNumber
    {
        get
        { 
            return _MyNumber;
        }
        set
        {
            _MyNumber = value;
            double _temp;
            string toBexamined = value;
            if (!toBexamined.Contains("."))
            {
                toBexamined += ".0";
            }
            if (toBexamined.EndsWith("."))
            {
                toBexamined += "0";
            }
            if (!double.TryParse(toBexamined, out _temp))
            {
                _MyNumber = _MyValidNumber.ToString();
            } 
            else
            {
                _MyValidNumber = _temp;
            }
            NotifyPropertyChanged(nameof(MyNumber)); }
    }
    
I would like to present a solution that is based on using a User Control - TextBoxDouble.
How we use it :
 <local:TextBoxDouble Number="{Binding SimpleNumber,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
the TextBoxDouble XAML is as following:
<UserControl x:Class="Problem19_ValidateANumber.TextBoxDouble"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Problem19_ValidateANumber"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" Name="Parent">
    <Grid>
        <TextBox Text="{Binding ElementName=Parent,Path=Text,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"   />
    </Grid>
</UserControl>
In the Code Behind we have defined 2 dependency properties: Text and Number. The 2 properties exchange the data. The Text Property is for the UI side and the Number is for the View Model property side.
public partial class TextBoxDouble : UserControl
    {
        public TextBoxDouble()
        {
            InitializeComponent();
        }
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set {
                SetValue(TextProperty, value);
                SetValue(TextProperty, value); 
            }
        }
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TextBoxDouble),
              new PropertyMetadata(string.Empty, new PropertyChangedCallback(TextPropertyChanged)));
       
        public double Number
        {
            get { return (double)GetValue(NumberProperty); }
            set
            {
                SetValue(NumberProperty, value);
            }
        }
        public static readonly DependencyProperty NumberProperty =
           DependencyProperty.Register("Number", typeof(double), typeof(TextBoxDouble),
             new PropertyMetadata(double.NaN, new PropertyChangedCallback(NumberPropertyChanged)));
        private static void TextPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TextBoxDouble ours = (TextBoxDouble)obj;
            if (e.NewValue == e.OldValue) return;
            double _temp;
            string toBexamined = (string)e.NewValue;
            if (!toBexamined.Contains("."))
            {
                toBexamined += ".0";
            }
            if (toBexamined.EndsWith("."))
            {
                toBexamined += "0";
            }
            if (!double.TryParse(toBexamined, out _temp))
            {
                ours.SetValue(TextProperty, ours.Number.ToString());
            }
            else
            {
                ours.SetValue(NumberProperty, _temp);
            }
        }
        private static void NumberPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            TextBoxDouble ours = (TextBoxDouble)obj;
            if (e.NewValue == e.OldValue) return;
            ours.SetValue(TextProperty, ours.Number.ToString());
        }
    }
Similar to what @Gilad Waisel suggested. I think the most simplest ways would be just to extend the TextBox class and enter your desired validation into the TexhChangeEvent:
  public class TextBoxDecimal : TextBox
    {
        readonly string CurrentSeperator;
        public TextBoxDecimal()
        {
            CultureInfo cultureInfo = CultureInfo.CurrentCulture;
            CurrentSeperator = cultureInfo.NumberFormat.CurrencyDecimalSeparator;
        }
        protected override void OnTextInput(TextCompositionEventArgs e)
        {
            if (double.TryParse(e.Text, out var value))
                base.OnTextInput(e);
            else if (e.Text == CurrentSeperator && !Text.Any(x => x == CurrentSeperator[0]))
                base.OnTextInput(e);
        }
    }
This is not conflicting with MVVM however does operate ONLY on the UI side.
Below is the working code to accept only double value:
    decimal _MyValidNumber;
    string _MyNumber;
    public string MyNumber
    {
        get
        {
            return _MyNumber;
        }
        set
        {
            if (decimal.TryParse(value, out decimal result))
            {
                _MyValidNumber = result;
                _MyNumber = value;
            }
            else
            {
                _MyNumber = "";
            }
            NotifyPropertyChanged(nameof(_MyNumber));
        }
    }