diff --git a/app/Extra.Designer.cs b/app/Extra.Designer.cs
index cd8677ce..8deb7a78 100644
--- a/app/Extra.Designer.cs
+++ b/app/Extra.Designer.cs
@@ -73,8 +73,8 @@ namespace GHelper
labelBacklightTitle = new Label();
panelBacklight = new Panel();
panelBacklightExtra = new Panel();
- numericBacklightPluggedTime = new NumericUpDown();
- numericBacklightTime = new NumericUpDown();
+ numericBacklightPluggedTime = new NumericUpDownWithUnit();
+ numericBacklightTime = new NumericUpDownWithUnit();
labelBacklightTimeout = new Label();
labelSpeed = new Label();
comboKeyboardSpeed = new RComboBox();
@@ -119,7 +119,7 @@ namespace GHelper
checkStatusLed = new CheckBox();
checkPerKeyRGB = new CheckBox();
panelPower = new Panel();
- numericHibernateAfter = new NumericUpDown();
+ numericHibernateAfter = new NumericUpDownWithUnit();
labelHibernateAfter = new Label();
pictureHibernate = new PictureBox();
toolTip = new ToolTip(components);
@@ -715,6 +715,7 @@ namespace GHelper
numericBacklightPluggedTime.Name = "numericBacklightPluggedTime";
numericBacklightPluggedTime.Size = new Size(140, 39);
numericBacklightPluggedTime.TabIndex = 1;
+ numericBacklightPluggedTime.Unit = "sec";
//
// numericBacklightTime
//
@@ -725,6 +726,7 @@ namespace GHelper
numericBacklightTime.Name = "numericBacklightTime";
numericBacklightTime.Size = new Size(140, 39);
numericBacklightTime.TabIndex = 2;
+ numericBacklightTime.Unit = "sec";
//
// labelBacklightTimeout
//
@@ -1323,6 +1325,7 @@ namespace GHelper
numericHibernateAfter.Maximum = new decimal(new int[] { 3000000, 0, 0, 0 });
numericHibernateAfter.Name = "numericHibernateAfter";
numericHibernateAfter.Size = new Size(152, 39);
+ numericHibernateAfter.Unit = "min";
numericHibernateAfter.TabIndex = 1;
//
// labelHibernateAfter
@@ -1714,8 +1717,8 @@ namespace GHelper
private Panel panelBacklightHeader;
private Panel panelBacklight;
private Panel panelBacklightExtra;
- private NumericUpDown numericBacklightPluggedTime;
- private NumericUpDown numericBacklightTime;
+ private NumericUpDownWithUnit numericBacklightPluggedTime;
+ private NumericUpDownWithUnit numericBacklightTime;
private Label labelBacklightTimeout;
private Label labelSpeed;
private RComboBox comboKeyboardSpeed;
@@ -1764,7 +1767,7 @@ namespace GHelper
private Panel panelPower;
private PictureBox pictureHibernate;
private Label labelHibernateAfter;
- private NumericUpDown numericHibernateAfter;
+ private NumericUpDownWithUnit numericHibernateAfter;
private CheckBox checkGPUFix;
private ToolTip toolTip;
private CheckBox checkBootSound;
diff --git a/app/UI/NumericUpDownWithUnit.cs b/app/UI/NumericUpDownWithUnit.cs
new file mode 100644
index 00000000..a521937f
--- /dev/null
+++ b/app/UI/NumericUpDownWithUnit.cs
@@ -0,0 +1,141 @@
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+public class NumericUpDownWithUnit : NumericUpDown
+{
+ #region| Fields |
+
+ private string unit = null;
+ private bool unitFirst = false;
+
+ #endregion
+
+ #region| Properties |
+
+ public string Unit
+ {
+ get => unit;
+ set
+ {
+ unit = value;
+
+ UpdateEditText();
+ }
+ }
+
+ public bool UnitFirst
+ {
+ get => unitFirst;
+ set
+ {
+ unitFirst = value;
+
+ UpdateEditText();
+ }
+ }
+
+ #endregion
+
+ #region| Methods |
+
+ ///
+ /// Method called when updating the numeric updown text.
+ ///
+ protected override void UpdateEditText()
+ {
+ // If there is a unit we handle it ourselfs, if there is not we leave it to the base class.
+ if (Unit != null && Unit != string.Empty)
+ {
+ if (UnitFirst)
+ {
+ Text = $"({Unit}) {Value}";
+ }
+ else
+ {
+ Text = $"{Value} ({Unit})";
+ }
+ }
+ else
+ {
+ base.UpdateEditText();
+ }
+ }
+
+ ///
+ /// Validate method called before actually updating the text.
+ /// This is exactly the same as the base class but it will use the new ParseEditText from this class instead.
+ ///
+ protected override void ValidateEditText()
+ {
+ // See if the edit text parses to a valid decimal considering the label unit
+ ParseEditText();
+ UpdateEditText();
+ }
+
+ ///
+ /// Converts the text displayed in the up-down control to a numeric value and evaluates it.
+ ///
+ protected new void ParseEditText()
+ {
+ try
+ {
+ // The only difference of this methods to the base one is that text is replaced directly
+ // with the property Text instead of using the regex.
+ // We now that the only characters that may be on the textbox are from the unit we provide.
+ // because the NumericUpDown handles invalid input from user for us.
+ // This is where the magic happens. This regex will match all characters from the unit
+ // (so your unit cannot have numbers). You can change this regex to fill your needs
+ var regex = new Regex($@"[^(?!{Unit} )]+");
+ var match = regex.Match(Text);
+
+ if (match.Success)
+ {
+ var text = match.Value;
+
+ // VSWhidbey 173332: Verify that the user is not starting the string with a "-"
+ // before attempting to set the Value property since a "-" is a valid character with
+ // which to start a string representing a negative number.
+ if (!string.IsNullOrEmpty(text) && !(text.Length == 1 && text == "-"))
+ {
+ if (Hexadecimal)
+ {
+ Value = Constrain(Convert.ToDecimal(Convert.ToInt32(Text, 16)));
+ }
+ else
+ {
+ Value = Constrain(Decimal.Parse(text, CultureInfo.CurrentCulture));
+ }
+ }
+ }
+ }
+ catch
+ {
+ // Leave value as it is
+ }
+ finally
+ {
+ UserEdit = false;
+ }
+ }
+
+ ///
+ /// Returns the provided value constrained to be within the min and max.
+ /// This is exactly the same as the one in base class (which is private so we can't directly use it).
+ ///
+ private decimal Constrain(decimal value)
+ {
+ if (value < Minimum)
+ {
+ value = Minimum;
+ }
+
+ if (value > Maximum)
+ {
+ value = Maximum;
+ }
+
+ return value;
+ }
+
+ #endregion
+}
\ No newline at end of file