访问附加属性中文本框的完整绑定值

时间:2018-05-28 12:16:57

标签: c# binding textbox attached-properties

使用附加属性时,我想在按下Key.Up或Key.Down时使用该值减去/增加文本框的值。

我定义了以下属性:

public static readonly DependencyProperty SmallFloatIncrementProperty = DependencyProperty.RegisterAttached(
      "SmallFloatIncrement",
      typeof(double),
      typeof(InputService),
      new UIPropertyMetadata(0.1));

    public static double GetSmallFloatIncrement(DependencyObject d)
    {
        return (double)d.GetValue(SmallFloatIncrementProperty);
    }

    public static void SetSmallFloatIncrement(DependencyObject d, double value)
    {
        d.SetValue(SmallFloatIncrementProperty, value);
    }

我还在TextBox上注册了PreviewKeyDown,并按照以下方式处理:

    if(e.Key == Key.Up)
    {
      IncrementOrDecrementValue((DependencyObject)sender, true);
    }
    else if (e.Key == Key.Down)
    {
      IncrementOrDecrementValue((DependencyObject)sender, false);              
    }

...

    private static void IncrementOrDecrementValue(DependencyObject sender, bool doIncrement)
    {
        if (sender is TextBox)
        {
          TextBox tb = (TextBox)sender;
          var increment = GetSmallFloatIncrement((DependencyObject)sender);

          var text = tb.Text;
          double textBoxValue = 0.0;
          if (!string.IsNullOrEmpty(text))
          {
             try{
               textBoxValue = Convert.ToDouble(text, FormatProvider);
             }
             catch (FormatException)   { }
          }

          tb.Text = Convert.ToString((doIncrement) ? textBoxValue + increment : textBoxValue - increment, FormatProvider);
          ValidateResult(sender);        
        }
    }

检索文本框的值时遇到问题。例如,如果绑定属性为1.234但绑定中定义了StringFormat = N1,则调用tb.Text会传递1.2而不是整个值。但是我需要将原始值增加指定的量(该值必须是增量的倍数)。有没有办法检索文本框的完整边界值?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

基本上您不想更改文本框的值,您希望通过键更改视图模型的值。因此,正确的解决方案是将此行为直接绑定到视图模型。 所以,这是附加属性保存值本身。

public static double GetSmallFloatIncrement(DependencyObject obj)
{
    return (double)obj.GetValue(SmallFloatIncrementProperty);
}

public static void SetSmallFloatIncrement(DependencyObject obj, double value)
{
    obj.SetValue(SmallFloatIncrementProperty, value);
}

public static readonly DependencyProperty SmallFloatIncrementProperty =
    DependencyProperty.RegisterAttached("SmallFloatIncrement", typeof(double), typeof(TextBoxExtensions),
        new PropertyMetadata(0.0));

实现此功能并打开/关闭它的另一个附加属性:

public static bool GetSmallFloatIncrementOn(DependencyObject obj)
{
    return (bool)obj.GetValue(SmallFloatIncrementOnProperty);
}

public static void SetSmallFloatIncrementOn(DependencyObject obj, bool value)
{
    obj.SetValue(SmallFloatIncrementOnProperty, value);
}

public static readonly DependencyProperty SmallFloatIncrementOnProperty =
    DependencyProperty.RegisterAttached("SmallFloatIncrementOn", typeof(bool), typeof(TextBoxExtensions),
        new PropertyMetadata(false, OnSmallFloatIncrementOn));

static void OnSmallFloatIncrementOn(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var textBox = (TextBox)d;

    void OnKeyDown(object sender, KeyEventArgs keyArgs)
    {
        if (keyArgs.Key == Key.Up)
            IncrementOrDecrementValue(textBox, .01);
        else if (keyArgs.Key == Key.Down)
            IncrementOrDecrementValue(textBox, -.01);
    }

    if ((bool)e.NewValue)
        textBox.PreviewKeyDown += OnKeyDown;
    else
        textBox.PreviewKeyDown -= OnKeyDown;
}

现在增加的函数变得简单了:

static void IncrementOrDecrementValue(TextBox textBox, double inc)
{
    var cur = GetSmallFloatIncrement(textBox);
    SetSmallFloatIncrement(textBox, cur + inc);
}

现在我们可以使用它了:

<TextBox Text="{Binding VMValue, StringFormat=F1}" 
             local:TextBoxExtensions.SmallFloatIncrement="{Binding VMValue, Mode=TwoWay}"
             local:TextBoxExtensions.SmallFloatIncrementOn="True"/>

注意:使用这些增量和字符串格式值,您必须按键10次,直到您在TextBox中看到值更改为止。但这是你可以根据自己的口味调整的。