WPF行为无法正常工作

时间:2016-03-01 18:19:22

标签: c# wpf attachedbehaviors

我正在尝试创建一个wpf行为。我所做的就是查找按键OemPeriodDecimalbackspacedelete。如果文本框中的字符串是101.55,并且用户通过将光标移回10来按下Decimal或OemPeriod,它将在10之后删除字符串1,字符串将变为10.55

该部分按预期工作。但真正的问题在于back (backspace)Delete键。

如果文本框中的文本是10.55并且光标位于.(插入符索引= 2)之后并且用户按下退格键,则插入符号将其位置移动-1(在十进制)并且在插入符号位置后添加55,文本变为1055.00Delete键也会出现相同的情况。

使用StringFormat={}{0:#.00}

格式化文字

这是我的代码,谁能告诉我什么是错的?

public class DecimalWatchingBehaviour : Behavior<UIElement> 
{

     protected override void OnAttached() 
     {
        base.OnAttached();
        TextBox t = AssociatedObject as TextBox;
        if (t != null) 
        {
            t.PreviewKeyUp += shiftCaretPosition;
        }
     }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        TextBox t = AssociatedObject as TextBox;
        if (t != null) 
        {
            t.PreviewKeyUp -= shiftCaretPosition;
        }
    }

    private void shiftCaretPosition(object sender, KeyEventArgs args) 
    {
        TextBox t = sender as TextBox;
        if (t == null) return;
        string txt = t.Text;
        if (!txt.Contains(".")) 
        {
            return;
        }
        int index = txt.IndexOf(".", StringComparison.Ordinal);
        int caretIndex = t.CaretIndex;
        if ((args.Key == Key.OemPeriod || args.Key == Key.Decimal)) 
        {
            t.Text = t.Text.Remove(t.CaretIndex, index);
            t.CaretIndex = t.Text.IndexOf(".", StringComparison.Ordinal) + 1;
        } else if (args.Key == Key.Back && txt.Substring(caretIndex < index ? caretIndex : index,
            caretIndex < index ? index - caretIndex : caretIndex - index) == ".") 
        {
            t.CaretIndex = index - 1;
        } else if (args.Key == Key.Delete && txt.Substring(caretIndex < index ? caretIndex : index,
            caretIndex < index ? index - caretIndex : caretIndex - index) == ".") 
        {
            t.CaretIndex = index + 1;
        }
    }
}

这是xaml名称空间声明

xmlns:behaviour="clr-namespace:Utils.UI.Input.Behaviour;assembly=Utils"
<UserControl.Resources>        
        <behaviour:DecimalWatchingBehaviour x:Key="decimalWatchingBehaviour" />
</UserControl.Resources>

xaml中的文本框

<TextBox
        Margin="5"
        Text="{Binding NewBatch.Cess,
               Mode=TwoWay,
               UpdateSourceTrigger=PropertyChanged,
               StringFormat={}{0:#.00}}" >
        <i:Interaction.Behaviors>
            <behaviour:DecimalWatchingBehaviour/>
        </i:Interaction.Behaviors>
</TextBox>

1 个答案:

答案 0 :(得分:0)

您可以参考以下简单事件处理程序代码段,它提供了类似的功能,即:将WPF TextBox1输入限制为数字输入和一些特殊键:

// PreviewKeyDown event proc: 
// only numeric and some special keys input allowed
TextBox1.PreviewKeyDown += (s, e) =>
{
    // intercept modifier "SHIFT" key
    if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
    { e.Handled = true; }

    // cast e.Key to int
    int _intKey = (int)e.Key;

    // allow the following key
    if (e.Key == Key.Back ||
        e.Key == Key.Delete ||
        e.Key == Key.Enter ||
        e.Key == Key.Return ||
        e.Key == Key.Tab ||
        e.Key == Key.OemPeriod ||
        e.Key == Key.OemComma ||
        e.Key == Key.Decimal ||
        e.Key == Key.Left ||
        e.Key == Key.Right ||
        (_intKey <= 43 && _intKey >= 34) ||
        (_intKey <= 84 && _intKey >= 73)) 
        {
              // the rest of the event handling code
              return;
        }
    else e.Handled = true;
};

其中TextBox1是目标WPF TextBox控件。不需要任何额外的XAML或代码。

希望这可能会有所帮助。