Skip to content

Commit 3fba68e

Browse files
committed
Merge pull request #2245 from xxMUROxx/hotfix/HexFormat
[WIP] Some fixes in NumericUpDown
2 parents 0330079 + b19929a commit 3fba68e

File tree

5 files changed

+144
-83
lines changed

5 files changed

+144
-83
lines changed

MahApps.Metro/Controls/DataGridNumericUpDownColumn.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public class DataGridNumericUpDownColumn : DataGridBoundColumn
1818
private string stringFormat = (string)NumericUpDown.StringFormatProperty.DefaultMetadata.DefaultValue;
1919
private bool hideUpDownButtons = (bool)NumericUpDown.HideUpDownButtonsProperty.DefaultMetadata.DefaultValue;
2020
private double upDownButtonsWidth = (double)NumericUpDown.UpDownButtonsWidthProperty.DefaultMetadata.DefaultValue;
21-
private Binding foregroundBinding;
2221

2322
static DataGridNumericUpDownColumn()
2423
{
@@ -117,26 +116,13 @@ private NumericUpDown GenerateNumericUpDown(bool isEditing, DataGridCell cell)
117116
if (numericUpDown == null)
118117
{
119118
numericUpDown = new NumericUpDown();
120-
// create binding to cell foreground to get changed brush from selection
121-
foregroundBinding = new Binding("Foreground") { Source = cell, Mode = BindingMode.OneWay };
122119
}
123120

124121
SyncProperties(numericUpDown);
125122

126123
ApplyStyle(isEditing, true, numericUpDown);
127124
ApplyBinding(Binding, numericUpDown, NumericUpDown.ValueProperty);
128125

129-
if (!isEditing && Equals(this.Foreground, SystemColors.ControlTextBrush))
130-
{
131-
// bind to cell foreground to get changed brush from selection
132-
ApplyBinding(foregroundBinding, numericUpDown, Control.ForegroundProperty);
133-
}
134-
else
135-
{
136-
// no foreground change for editing
137-
BindingOperations.ClearBinding(numericUpDown, Control.ForegroundProperty);
138-
}
139-
140126
numericUpDown.Minimum = Minimum;
141127
numericUpDown.Maximum = Maximum;
142128
numericUpDown.StringFormat = StringFormat;

MahApps.Metro/Controls/Helper/TextBoxHelper.cs

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,6 @@ public static void SetUseFloatingWatermark(DependencyObject obj, bool value)
188188
obj.SetValue(UseFloatingWatermarkProperty, value);
189189
}
190190

191-
private static void SetTextLength(DependencyObject obj, int value)
192-
{
193-
obj.SetValue(TextLengthProperty, value);
194-
obj.SetValue(HasTextProperty, value >= 1);
195-
}
196-
197191
/// <summary>
198192
/// Gets if the attached TextBox has text.
199193
/// </summary>
@@ -207,7 +201,7 @@ public static void SetHasText(DependencyObject obj, bool value)
207201
obj.SetValue(HasTextProperty, value);
208202
}
209203

210-
static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
204+
private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
211205
{
212206
if (d is TextBox)
213207
{
@@ -250,44 +244,67 @@ static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedE
250244
{
251245
var numericUpDown = d as NumericUpDown;
252246
numericUpDown.SelectAllOnFocus = (bool)e.NewValue;
247+
if ((bool)e.NewValue)
248+
{
249+
numericUpDown.ValueChanged += OnNumericUpDownValueChaged;
250+
numericUpDown.GotFocus += NumericUpDownGotFocus;
251+
}
252+
else
253+
{
254+
numericUpDown.ValueChanged -= OnNumericUpDownValueChaged;
255+
numericUpDown.GotFocus -= NumericUpDownGotFocus;
256+
}
253257
}
254258
}
255259

256-
static void TextChanged(object sender, TextChangedEventArgs e)
260+
private static void SetTextLength<TDependencyObject>(TDependencyObject sender, Func<TDependencyObject, int> funcTextLength) where TDependencyObject : DependencyObject
257261
{
258-
var txtBox = sender as TextBox;
259-
if (txtBox == null)
260-
return;
261-
SetTextLength(txtBox, txtBox.Text.Length);
262+
if (sender != null)
263+
{
264+
var value = funcTextLength(sender);
265+
sender.SetValue(TextLengthProperty, value);
266+
sender.SetValue(HasTextProperty, value >= 1);
267+
}
262268
}
263269

264-
static void PasswordChanged(object sender, RoutedEventArgs e)
270+
private static void TextChanged(object sender, RoutedEventArgs e)
265271
{
266-
var passBox = sender as PasswordBox;
267-
if (passBox == null)
268-
return;
269-
SetTextLength(passBox, passBox.Password.Length);
272+
SetTextLength(sender as TextBox, textBox => textBox.Text.Length);
270273
}
271274

272-
static void TextBoxGotFocus(object sender, RoutedEventArgs e)
275+
private static void OnNumericUpDownValueChaged(object sender, RoutedEventArgs e)
273276
{
274-
var txtBox = sender as TextBox;
275-
if (txtBox == null)
276-
return;
277-
if (GetSelectAllOnFocus(txtBox))
278-
{
279-
txtBox.Dispatcher.BeginInvoke((Action)(txtBox.SelectAll));
280-
}
277+
SetTextLength(sender as NumericUpDown, numericUpDown => numericUpDown.Value.HasValue ? 1 : 0);
278+
}
279+
280+
private static void PasswordChanged(object sender, RoutedEventArgs e)
281+
{
282+
SetTextLength(sender as PasswordBox, passwordBox => passwordBox.Password.Length);
281283
}
282284

283-
static void PasswordGotFocus(object sender, RoutedEventArgs e)
285+
private static void TextBoxGotFocus(object sender, RoutedEventArgs e)
284286
{
285-
var passBox = sender as PasswordBox;
286-
if (passBox == null)
287-
return;
288-
if (GetSelectAllOnFocus(passBox))
287+
ControlGotFocus(sender as TextBox, textBox => textBox.SelectAll);
288+
}
289+
290+
private static void NumericUpDownGotFocus(object sender, RoutedEventArgs e)
291+
{
292+
ControlGotFocus(sender as NumericUpDown, numericUpDown => numericUpDown.SelectAll);
293+
}
294+
295+
private static void PasswordGotFocus(object sender, RoutedEventArgs e)
296+
{
297+
ControlGotFocus(sender as PasswordBox, passwordBox => passwordBox.SelectAll);
298+
}
299+
300+
private static void ControlGotFocus<TDependencyObject>(TDependencyObject sender, Func<TDependencyObject, Action> funcSelectAll) where TDependencyObject : DependencyObject
301+
{
302+
if (sender != null)
289303
{
290-
passBox.Dispatcher.BeginInvoke((Action)(passBox.SelectAll));
304+
if (GetSelectAllOnFocus(sender))
305+
{
306+
sender.Dispatcher.BeginInvoke(funcSelectAll, sender);
307+
}
291308
}
292309
}
293310

@@ -335,8 +352,6 @@ public static void SetIsClearTextButtonBehaviorEnabled(Button obj, bool value)
335352
obj.SetValue(IsClearTextButtonBehaviorEnabledProperty, value);
336353
}
337354

338-
339-
340355
public static ICommand GetButtonCommand(DependencyObject d)
341356
{
342357
return (ICommand)d.GetValue(ButtonCommandProperty);
@@ -444,22 +459,22 @@ private static void ButtonCommandOrClearTextChanged(DependencyObject d, Dependen
444459
if (textbox != null)
445460
{
446461
// only one loaded event
447-
textbox.Loaded -= TextBoxLoaded;
448-
textbox.Loaded += TextBoxLoaded;
462+
textbox.Loaded -= TextChanged;
463+
textbox.Loaded += TextChanged;
449464
if (textbox.IsLoaded)
450465
{
451-
TextBoxLoaded(textbox, new RoutedEventArgs());
466+
TextChanged(textbox, new RoutedEventArgs());
452467
}
453468
}
454469
var passbox = d as PasswordBox;
455470
if (passbox != null)
456471
{
457472
// only one loaded event
458-
passbox.Loaded -= PassBoxLoaded;
459-
passbox.Loaded += PassBoxLoaded;
473+
passbox.Loaded -= PasswordChanged;
474+
passbox.Loaded += PasswordChanged;
460475
if (passbox.IsLoaded)
461476
{
462-
PassBoxLoaded(passbox, new RoutedEventArgs());
477+
PasswordChanged(passbox, new RoutedEventArgs());
463478
}
464479
}
465480
var combobox = d as ComboBox;
@@ -483,23 +498,5 @@ static void ComboBoxLoaded(object sender, RoutedEventArgs e)
483498
comboBox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(comboBox.Text) || comboBox.SelectedItem != null);
484499
}
485500
}
486-
487-
static void PassBoxLoaded(object sender, RoutedEventArgs e)
488-
{
489-
var passbox = sender as PasswordBox;
490-
if (passbox != null)
491-
{
492-
passbox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(passbox.Password));
493-
}
494-
}
495-
496-
static void TextBoxLoaded(object sender, RoutedEventArgs e)
497-
{
498-
var textbox = sender as TextBox;
499-
if (textbox != null)
500-
{
501-
textbox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(textbox.Text));
502-
}
503-
}
504501
}
505502
}

MahApps.Metro/Controls/NumericUpDown.cs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace MahApps.Metro.Controls
55
using System.Globalization;
66
using System.Linq;
77
using System.Reflection;
8+
using System.Text.RegularExpressions;
89
using System.Windows;
910
using System.Windows.Controls;
1011
using System.Windows.Controls.Primitives;
@@ -157,7 +158,9 @@ private static void InterceptManualEnterChangedCallback(DependencyObject depende
157158
typeof(bool),
158159
typeof(NumericUpDown),
159160
new FrameworkPropertyMetadata(true, OnHasDecimalsChanged));
160-
161+
162+
private static readonly Regex RegexStringFormatHexadecimal = new Regex(@"^(?<complexHEX>.*{\d:X\d+}.*)?(?<simpleHEX>X\d+)?$", RegexOptions.Compiled);
163+
161164
private const double DefaultInterval = 1d;
162165
private const int DefaultDelay = 500;
163166
private const string ElementNumericDown = "PART_NumericDown";
@@ -855,6 +858,7 @@ private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChang
855858
var numericUpDown = (NumericUpDown)d;
856859

857860
numericUpDown.CoerceValue(ValueProperty);
861+
numericUpDown.Value = (double?)CoerceValue(numericUpDown, numericUpDown.Value);
858862
numericUpDown.OnMaximumChanged((double)e.OldValue, (double)e.NewValue);
859863
numericUpDown.EnableDisableUpDown();
860864
}
@@ -865,6 +869,7 @@ private static void OnMinimumChanged(DependencyObject d, DependencyPropertyChang
865869

866870
numericUpDown.CoerceValue(ValueProperty);
867871
numericUpDown.CoerceValue(MaximumProperty);
872+
numericUpDown.Value = (double?)CoerceValue(numericUpDown, numericUpDown.Value);
868873
numericUpDown.OnMinimumChanged((double)e.OldValue, (double)e.NewValue);
869874
numericUpDown.EnableDisableUpDown();
870875
}
@@ -886,6 +891,7 @@ private static void OnStringFormatChanged(DependencyObject d, DependencyProperty
886891
{
887892
nud.InternalSetText(nud.Value);
888893
}
894+
nud.HasDecimals = !RegexStringFormatHexadecimal.IsMatch((string)e.NewValue);
889895
}
890896

891897
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -924,14 +930,9 @@ private void InternalSetText(double? newValue)
924930
{
925931
_valueTextBox.Text = newValue.Value.ToString(culture);
926932
}
927-
else if (!StringFormat.Contains("{"))
928-
{
929-
// then we may have a StringFormat of e.g. "N0"
930-
_valueTextBox.Text = newValue.Value.ToString(StringFormat, culture);
931-
}
932933
else
933934
{
934-
_valueTextBox.Text = string.Format(culture, StringFormat, newValue.Value);
935+
FormatValue(newValue, culture);
935936
}
936937

937938
if ((bool)GetValue(TextBoxHelper.IsMonitoringProperty))
@@ -940,6 +941,35 @@ private void InternalSetText(double? newValue)
940941
}
941942
}
942943

944+
private void FormatValue(double? newValue, CultureInfo culture)
945+
{
946+
var match = RegexStringFormatHexadecimal.Match(StringFormat);
947+
if (match.Success)
948+
{
949+
if (match.Groups["simpleHEX"].Success)
950+
{
951+
// HEX DOES SUPPORT INT ONLY.
952+
_valueTextBox.Text = ((int)newValue.Value).ToString(match.Groups["simpleHEX"].Value, culture);
953+
}
954+
else if (match.Groups["complexHEX"].Success)
955+
{
956+
_valueTextBox.Text = string.Format(culture, match.Groups["complexHEX"].Value, (int)newValue.Value);
957+
}
958+
}
959+
else
960+
{
961+
if (!StringFormat.Contains("{"))
962+
{
963+
// then we may have a StringFormat of e.g. "N0"
964+
_valueTextBox.Text = newValue.Value.ToString(StringFormat, culture);
965+
}
966+
else
967+
{
968+
_valueTextBox.Text = string.Format(culture, StringFormat, newValue.Value);
969+
}
970+
}
971+
}
972+
943973
private ScrollViewer TryFindScrollViewer()
944974
{
945975
_valueTextBox.ApplyTemplate();

0 commit comments

Comments
 (0)