If you want to avoid using code-behind, you can convert the above answer into a behavior by creating a class (e.g. DigitsOnlyBehavior) that contains an AttachedProperty. When the attached property is set, you register the handler which is defined and implemented in your behavior class.
One short example:
public static class MyBehavior
{
public static readonly DependencyProperty AllowOnlyDigitsProperty = DependencyProperty.RegisterAttached(
"AllowOnlyDigits", typeof(bool), typeof(MyBehavior), new PropertyMetadata(default(bool), OnAllowOnlyDigitsChanged));
private static void OnAllowOnlyDigitsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBox = d as TextBox;
if (textBox == null) return;
textBox.PreviewTextInput += PreviewTextBoxInput;
}
public static void SetAllowOnlyDigits(DependencyObject element, bool value)
{
element.SetValue(AllowOnlyDigitsProperty, value);
}
private static void PreviewTextBoxInput(object sender, TextCompositionEventArgs e)
{
var textbox = sender as TextBox;
if (!char.IsDigit(e.Text, e.Text.Length - 1))
e.Handled = true;
}
public static bool GetAllowOnlyDigits(DependencyObject element)
{
return (bool) element.GetValue(AllowOnlyDigitsProperty);
}
}
As you can see the PreviewTextBoxInput function is mainly what the previous post suggests.
You can now "attach" that behavior in your XAML like this:
<TextBox local:MyBehavior.AllowOnlyDigits="True" />
This solution is not fully complete, since it does not support changing the property (it will attach the handler each time the property changes, so it assumes you only set it once via XAML). But if you don't want to change this behavior during runtime, you're fine.