I have a common class filled with generic functions like the one below to parse a text box:
public static void DoubleParse_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Decimal)
{
var textBox = sender as TextBox;
if (textBox != null)
textBox.Text += Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);
}
else
{
e.Handled = (e.Key >= Key.D0 && e.Key <= Key.D9) ||
(e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) ||
e.Key == Key.Back || e.Key == Key.Delete ||
e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Unknown;
}
}
I thought I could use this everywhere across my pages as a single source for TextBox keydown events. New to MVVM implementation in WP8, curious if there's a way to achieve this?
In the spirit of MVVM (though I'm not a purist), I understand it doesn't need to be in the viewmodel specifically, but I'd still like it centralized.
A quick note:
- The class isn't static, I understand I can't use that directly in xaml.
- I thought to make the class some kind of StaticResource and reference the functions in xaml. But that doesn't seem to work.
- I'm currently just using pass through functions in the code-behind and passing the sender on to the static functions.
You want an Attached Behavior.
public static class TextBoxBehavior
{
public static bool GetAllowOnlyDecimalInput(TextBox texbox)
{
return (bool)texbox.GetValue(AllowOnlyDecimalInputProperty);
}
public static void SetAllowOnlyDecimalInput(
TextBox texbox, bool value)
{
texbox.SetValue(AllowOnlyDecimalInputProperty, value);
}
public static readonly DependencyProperty AllowOnlyDecimalInputProperty =
DependencyProperty.RegisterAttached(
"AllowOnlyDecimalInput",
typeof(bool),
typeof(TextBox),
new PropertyMetadata(false, OnAllowOnlyDecimalInputChanged));
static void OnAllowOnlyDecimalInputChanged(
DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
TextBox item = depObj as TextBox;
if (item == null)
return;
if (e.NewValue is bool == false)
return;
if ((bool)e.NewValue)
item.KeyDown += OnTextBoxDoubleParse_KeyDown;
else
item.KeyDown -= OnTextBoxDoubleParse_KeyDown;
}
static void OnTextBoxDoubleParse_KeyDown(object sender, KeyEventArgs e)
{
if (!Object.ReferenceEquals(sender, e.OriginalSource))
return;
TextBox item = e.OriginalSource as TextBox;
if (item != null) {
if (e.Key == Key.Decimal)
{
var textBox = sender as TextBox;
if (textBox != null)
textBox.Text += Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);
}
else
{
e.Handled = (e.Key >= Key.D0 && e.Key <= Key.D9) ||
(e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9) ||
e.Key == Key.Back || e.Key == Key.Delete ||
e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Unknown;
}
}
}
#endregion // AllowOnlyDecimalInput
}
In XAML use it with
<TextBox my:TextBoxBehavior.AllowOnlyDecimalInput="True" />
You can also set this in an WPF Style and have it reusable within all or many controls rather than adding the property each time manually.