简体   繁体   中英

Attached Property on TextBox WPF

My problem is simple I have a textbox in WPF where you can type a number. I want three things when I press specific keys :

  • Enter : the value is sent
  • Up : the value is increased then sent
  • Down : the value is decreased then sent

I have made 3 attached properties but it works only for the Key Enter.

<TextBox Margin="5,0"  hlp:TextboxBehaviors.KeyToValid="Enter" hlp:Decrease.KeyToDecrease="Down" hlp:Increase.KeyToIncrease="Up"  Text="{Binding Target, Mode=TwoWay, UpdateSourceTrigger=Explicit, Converter={StaticResource kiloConverter}, ValidatesOnNotifyDataErrors=True, ValidatesOnExceptions=True}" />

The code of the class :

public static class Decrease
{
    private static Key TriggeredKey = Key.Down;
    public static Key GetKeyToDecrease(DependencyObject obj)
    {
        return (Key)obj.GetValue(KeyToDecreaseProperty);
    }

    /// <summary>
    /// Sert uniquement à s'attacher à la TextBox (une seule fois à l'init de l'interface)
    /// </summary>
    public static void SetKeyToDecrease(DependencyObject obj, Key value)
    {
        var tb = obj as TextBox;
        if (tb != null)
            tb.KeyDown += OnKeyDown;
    }

    /// <summary>
    /// Evenement classique
    /// </summary>
    private static void OnKeyDown(object sender, KeyEventArgs e)
    {
        var tbCurrent = sender as TextBox;
        int selectedpos;

        if (tbCurrent != null && e.Key == TriggeredKey)
        {
            if (tbCurrent.SelectionStart > 0)
            {
                if (!tbCurrent.Text.Contains("."))
                {
                    int exp = tbCurrent.Text.Length - tbCurrent.SelectionStart;
                    tbCurrent.Text = (Convert.ToDouble(tbCurrent.Text) - Math.Pow(10, exp)).ToString();
                    selectedpos = tbCurrent.Text.Length - exp;
                }
                else
                {
                    int exp;
                    if (tbCurrent.SelectionStart > tbCurrent.Text.IndexOf('.') + 1)
                    {
                        exp = tbCurrent.Text.IndexOf('.') - tbCurrent.SelectionStart + 1;
                    }
                    else if (tbCurrent.SelectionStart < tbCurrent.Text.IndexOf('.') + 1)
                    {
                        exp = tbCurrent.Text.IndexOf('.') - tbCurrent.SelectionStart;
                    }
                    else
                    {
                        return;
                    }

                    tbCurrent.Text = (Convert.ToDouble(tbCurrent.Text) - Math.Pow(10, exp)).ToString("0.00");

                    if (exp < 0)
                    {
                        selectedpos = tbCurrent.Text.IndexOf('.') - exp + 1;
                    }
                    else
                    {
                        if (tbCurrent.Text.IndexOf('.') - exp < 0)
                        {
                            selectedpos = 0;
                        }
                        else
                        {
                            selectedpos = tbCurrent.Text.IndexOf('.') - exp;
                        }
                    }
                }

                BindingExpression binding = tbCurrent.GetBindingExpression(TextBox.TextProperty);
                if (binding != null)
                {
                    binding.UpdateSource();
                }

                tbCurrent.SelectionLength = 0;
                if (selectedpos >= 0)
                {
                    tbCurrent.SelectionStart = selectedpos;
                }
                else
                {
                    tbCurrent.SelectionStart = 0;
                }
            }
        }
    }

    // Using a DependencyProperty as the backing store for KeyToValid.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty KeyToDecreaseProperty =
        DependencyProperty.RegisterAttached("KeyToDecrease", typeof(Key), typeof(TextBox), new PropertyMetadata(TriggeredKey));

}

This the code for the Decrease attached behavior the two others are designed in the same way.

The decrease and the increase don't trigger the event ! The enter does...

The decrease and the increase don't trigger the event ! The enter does...

Handle the Preview KeyDown event:

public static void SetKeyToDecrease(DependencyObject obj, Key value)
{
    var tb = obj as TextBox;
    if (tb != null)
        tb.PreviewKeyDown += OnKeyDown;
}

The TextBox control handles and "swallows" certain key presses on its own. That's why the KeyDown event isn't fired in your behaviour.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM