Skip to content

Commit

Permalink
Merge pull request #55 from jholzer/master
Browse files Browse the repository at this point in the history
Bugfix: Format-Text must return parsed value, else value in textbox will be overwritten with "LastEditingNumericValue" if "IsUpdateValueWhenLostFocus" is enabled on lost focus
  • Loading branch information
Dirkster99 committed Mar 24, 2023
2 parents 8c593b0 + a756b40 commit 2b3bd4a
Show file tree
Hide file tree
Showing 24 changed files with 119 additions and 558 deletions.
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/ByteUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
MouseWheelAccelaratorKey="{Binding AccelModifierKey, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/DecimalUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/DoubleUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/FloatUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/LongUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/NumericUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/PercentageUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue, Converter={StaticResource FactorToDoubleConverter}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MinValue="{Binding MinimumValue, Converter={StaticResource FactorToDoubleConverter}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/SByteUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/ShortUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/UIntegerUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/ULongUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
1 change: 1 addition & 0 deletions source/Demo/UpDownDemoLib/Views/UShortUpDownDemo.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
IsDisplayLengthFixed="True"
IsMouseDragEnabled="{Binding ElementName=IsMouseDragEnabledCheckBox, Path=IsChecked}"
IsReadOnly="False"
IsUpdateValueWhenLostFocus="True"
LargeStepSize="{Binding LargeStepSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
MaxValue="{Binding MaximumValue}"
MinValue="{Binding MinimumValue}"
Expand Down
52 changes: 38 additions & 14 deletions source/NumericUpDownLib/Base/AbstractBaseUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace NumericUpDownLib.Base
using NumericUpDownLib.Enums;
using NumericUpDownLib.Models;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
Expand Down Expand Up @@ -1159,21 +1160,44 @@ protected string FormatNumber(T number)
}

/// <summary>
/// Checks if the current string entered in the textbox is:
/// 1) A valid number (syntax)
/// 2) within bounds (Min &lt;= number &lt;= Max )
///
/// 3) adjusts the string if it appears to be invalid and
///
/// 4) <paramref name="formatNumber"/> true:
/// Applies the FormatString property to format the text in a certain way
/// </summary>
/// <param name="text"></param>
/// <param name="formatNumber"></param>
/// <returns>the value of the string with special format</returns>
protected abstract T FormatText(string text, bool formatNumber = true);
/// Checks if the current string entered in the textbox is:
/// 1) A valid number (syntax)
/// 2) within bounds (Min &lt;= number &lt;= Max )
///
/// 3) adjusts the string if it appears to be invalid and
///
/// 4) <paramref name="formatNumber"/> true:
/// Applies the FormatString property to format the text in a certain way
/// </summary>
/// <param name="text"></param>
/// <param name="formatNumber"></param>
/// <returns>the value of the string with special format</returns>
protected T FormatText(string text, bool formatNumber = true)
{
if (_PART_TextBox == null)
return Value;

/// <summary>
T number = default;
// Does this text represent a valid number ?
if (ParseText(text, out number))
{
number = CoerceValue(number);

_PART_TextBox.Text = FormatNumber(number);
_PART_TextBox.SelectionStart = 0;

return number;
}

// Reset to last value since string does not appear to represent a number
_PART_TextBox.SelectionStart = 0;
_PART_TextBox.Text = FormatNumber(Value);
return LastEditingNumericValue;
}

protected abstract bool ParseText(string text, out T number);

/// <summary>
/// Verify the text is valid or not while use is typing
/// </summary>
/// <param name="text"></param>
Expand Down
68 changes: 12 additions & 56 deletions source/NumericUpDownLib/ByteUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,62 +321,18 @@ protected override bool VerifyText(string text, ref Byte tempValue)
return false;
}

/// <summary>
/// Checks if the current string entered in the textbox is valid
/// and conforms to a known format
/// (<see cref="AbstractBaseUpDown{T}"/> base method for more details).
/// </summary>
/// <param name="text"></param>
/// <param name="formatNumber"></param>
protected override byte FormatText(string text, bool formatNumber = true)
{
if (_PART_TextBox == null)
return Value;

byte number = 0;
// Does this text represent a valid number ?
if (byte.TryParse(text, base.NumberStyle,
CultureInfo.CurrentCulture, out number) == true)
{
// yes -> but is the number within bounds?
if (number > MaxValue)
{
// Larger than allowed maximum
_PART_TextBox.Text = FormatNumber(MaxValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
if (number < MinValue)
{
// Smaller than allowed minimum
_PART_TextBox.Text = FormatNumber(MinValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
// Number is valid and within bounds, just format if requested
if (formatNumber == true)
_PART_TextBox.Text = FormatNumber(number);
}
}
}
else
{
// Reset to last value since string does not appear to represent a number
_PART_TextBox.SelectionStart = 0;
_PART_TextBox.Text = FormatNumber(Value);
}
return LastEditingNumericValue;
}

/// <summary>
/// Determines whether the step size in the <paramref name="value"/> parameter
/// is larger 0 (valid) or not.
/// </summary>
/// <param name="value">returns true for valid values, otherwise false.</param>
/// <returns></returns>
private static bool IsValidStepSizeReading(object value)
protected override bool ParseText(string text, out byte number)
{
return byte.TryParse(text, base.NumberStyle, CultureInfo.CurrentCulture, out number);
}

/// <summary>
/// Determines whether the step size in the <paramref name="value"/> parameter
/// is larger 0 (valid) or not.
/// </summary>
/// <param name="value">returns true for valid values, otherwise false.</param>
/// <returns></returns>
private static bool IsValidStepSizeReading(object value)
{
byte v = (byte)value;
return (v > 0);
Expand Down
67 changes: 12 additions & 55 deletions source/NumericUpDownLib/DecimalUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,61 +322,18 @@ protected override bool VerifyText(string text, ref Decimal tempValue)
return false;
}

/// <summary>
/// Checks if the current string entered in the textbox is valid
/// and conforms to a known format
/// (<see cref="AbstractBaseUpDown{T}"/> base method for more details).
/// </summary>
/// <param name="text"></param>
/// <param name="formatNumber"></param>
protected override decimal FormatText(string text, bool formatNumber = true)
{
if (_PART_TextBox == null)
return Value;
decimal number = 0;
// Does this text represent a valid number ?
if (decimal.TryParse(text, base.NumberStyle,
CultureInfo.CurrentCulture, out number) == true)
{
// yes -> but is the number within bounds?
if (number > MaxValue)
{
// Larger than allowed maximum
_PART_TextBox.Text = FormatNumber(MaxValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
if (number < MinValue)
{
// Smaller than allowed minimum
_PART_TextBox.Text = FormatNumber(MinValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
// Number is valid and within bounds, just format if requested
if (formatNumber == true)
_PART_TextBox.Text = FormatNumber(number);
}
}
}
else
{
// Reset to last value since string does not appear to represent a number
_PART_TextBox.SelectionStart = 0;
_PART_TextBox.Text = FormatNumber(Value);
}
return LastEditingNumericValue;
}

/// <summary>
/// Determines whether the step size in the <paramref name="value"/> parameter
/// is larger 0 (valid) or not.
/// </summary>
/// <param name="value">returns true for valid values, otherwise false.</param>
/// <returns></returns>
private static bool IsValidStepSizeReading(object value)
protected override bool ParseText(string text, out decimal number)
{
return decimal.TryParse(text, base.NumberStyle, CultureInfo.CurrentCulture, out number);
}

/// <summary>
/// Determines whether the step size in the <paramref name="value"/> parameter
/// is larger 0 (valid) or not.
/// </summary>
/// <param name="value">returns true for valid values, otherwise false.</param>
/// <returns></returns>
private static bool IsValidStepSizeReading(object value)
{
decimal v = (decimal)value;
return (v > 0);
Expand Down
51 changes: 4 additions & 47 deletions source/NumericUpDownLib/DoubleUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,53 +325,10 @@ protected override bool VerifyText(string text, ref double tempValue)
return false;
}

/// <summary>
/// Checks if the current string entered in the textbox is valid
/// and conforms to a known format
/// (<see cref="AbstractBaseUpDown{T}"/> base method for more details).
/// </summary>
/// <param name="text"></param>
/// <param name="formatNumber"></param>
protected override double FormatText(string text, bool formatNumber = true)
{
if (_PART_TextBox == null)
return Value;
double number = 0;
// Does this text represent a valid number ?
if (double.TryParse(text, base.NumberStyle,
CultureInfo.CurrentCulture, out number) == true)
{
// yes -> but is the number within bounds?
if (number > MaxValue)
{
// Larger than allowed maximum
_PART_TextBox.Text = FormatNumber(MaxValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
if (number < MinValue)
{
// Smaller than allowed minimum
_PART_TextBox.Text = FormatNumber(MinValue);
_PART_TextBox.SelectionStart = 0;
}
else
{
// Number is valid and within bounds, just format if requested
if (formatNumber == true)
_PART_TextBox.Text = FormatNumber(number);
}
}
}
else
{
// Reset to last value since string does not appear to represent a number
_PART_TextBox.SelectionStart = 0;
_PART_TextBox.Text = FormatNumber(Value);
}
return LastEditingNumericValue;
}
protected override bool ParseText(string text, out double number)
{
return double.TryParse(text, base.NumberStyle, CultureInfo.CurrentCulture, out number);
}

/// <summary>
/// Determines whether the step size in the <paramref name="value"/> parameter
Expand Down

0 comments on commit 2b3bd4a

Please sign in to comment.