With an attached property, I want to de-/increase the value of a textbox by that value when hitting Key.Up or Key.Down.
I defined the following property:
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);
}
I have also registered for PreviewKeyDown on my TextBox and handle it like this:
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);
}
}
I run into propblems when retrieving the value of the textbox. If for example the bound property is 1.234 but there is a StringFormat = N1 defined in the binding, the call tb.Text delivers 1.2 instead of the entire value. But I need to increment the original value by the specified amount (the value must be a multiple of the increment). Is there a way to retrieve the complete bound value of the textbox?
Thanks for your help!
Essentially you don't want to change the textbox's value, you want to alter the view-model's value by the keys. Therefore the correct solution is to bind this behavior directly to the view-model. So, here's the attached property holding the value itself.
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));
Another attached property to implement this functionality and toggle it on/off:
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;
}
The function to increment gets simple now:
static void IncrementOrDecrementValue(TextBox textBox, double inc)
{
var cur = GetSmallFloatIncrement(textBox);
SetSmallFloatIncrement(textBox, cur + inc);
}
And now we can use it:
<TextBox Text="{Binding VMValue, StringFormat=F1}"
local:TextBoxExtensions.SmallFloatIncrement="{Binding VMValue, Mode=TwoWay}"
local:TextBoxExtensions.SmallFloatIncrementOn="True"/>
Note: with these increment and string format values you'll have to push the key 10 times until you see a value change in the TextBox. But this is something you can adjust to your taste.
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.