Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some fixes in NumericUpDown #2245

Merged
merged 13 commits into from
Dec 22, 2015
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 54 additions & 57 deletions MahApps.Metro/Controls/Helper/TextBoxHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,6 @@ public static void SetUseFloatingWatermark(DependencyObject obj, bool value)
obj.SetValue(UseFloatingWatermarkProperty, value);
}

private static void SetTextLength(DependencyObject obj, int value)
{
obj.SetValue(TextLengthProperty, value);
obj.SetValue(HasTextProperty, value >= 1);
}

/// <summary>
/// Gets if the attached TextBox has text.
/// </summary>
Expand All @@ -207,7 +201,7 @@ public static void SetHasText(DependencyObject obj, bool value)
obj.SetValue(HasTextProperty, value);
}

static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox)
{
Expand Down Expand Up @@ -250,44 +244,67 @@ static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedE
{
var numericUpDown = d as NumericUpDown;
numericUpDown.SelectAllOnFocus = (bool)e.NewValue;
if ((bool)e.NewValue)
{
numericUpDown.ValueChanged += OnNumericUpDownValueChaged;
numericUpDown.GotFocus += NumericUpDownGotFocus;
}
else
{
numericUpDown.ValueChanged += OnNumericUpDownValueChaged;
numericUpDown.GotFocus += NumericUpDownGotFocus;
}
}
}

static void TextChanged(object sender, TextChangedEventArgs e)
private static void SetTextLength<TDependencyObject>(TDependencyObject sender, Func<TDependencyObject, int> funcTextLength) where TDependencyObject : DependencyObject
{
var txtBox = sender as TextBox;
if (txtBox == null)
return;
SetTextLength(txtBox, txtBox.Text.Length);
if (sender != null)
{
var value = funcTextLength(sender);
sender.SetValue(TextLengthProperty, value);
sender.SetValue(HasTextProperty, value >= 1);
}
}

static void PasswordChanged(object sender, RoutedEventArgs e)
private static void TextChanged(object sender, RoutedEventArgs e)
{
var passBox = sender as PasswordBox;
if (passBox == null)
return;
SetTextLength(passBox, passBox.Password.Length);
SetTextLength(sender as TextBox, textBox => textBox.Text.Length);
}

static void TextBoxGotFocus(object sender, RoutedEventArgs e)
private static void OnNumericUpDownValueChaged(object sender, RoutedEventArgs e)
{
var txtBox = sender as TextBox;
if (txtBox == null)
return;
if (GetSelectAllOnFocus(txtBox))
{
txtBox.Dispatcher.BeginInvoke((Action)(txtBox.SelectAll));
}
SetTextLength(sender as NumericUpDown, numericUpDown => numericUpDown.Value.HasValue ? 1 : 0);
}

private static void PasswordChanged(object sender, RoutedEventArgs e)
{
SetTextLength(sender as PasswordBox, passwordBox => passwordBox.Password.Length);
}

static void PasswordGotFocus(object sender, RoutedEventArgs e)
private static void TextBoxGotFocus(object sender, RoutedEventArgs e)
{
var passBox = sender as PasswordBox;
if (passBox == null)
return;
if (GetSelectAllOnFocus(passBox))
ControlGotFocus(sender as TextBox, textBox => textBox.SelectAll);
}

private static void NumericUpDownGotFocus(object sender, RoutedEventArgs e)
{
ControlGotFocus(sender as NumericUpDown, numericUpDown => numericUpDown.SelectAll);
}

private static void PasswordGotFocus(object sender, RoutedEventArgs e)
{
ControlGotFocus(sender as PasswordBox, passwordBox => passwordBox.SelectAll);
}

private static void ControlGotFocus<TDependencyObject>(TDependencyObject sender, Func<TDependencyObject, Action> funcSelectAll) where TDependencyObject : DependencyObject
{
if (sender != null)
{
passBox.Dispatcher.BeginInvoke((Action)(passBox.SelectAll));
if (GetSelectAllOnFocus(sender))
{
sender.Dispatcher.BeginInvoke(funcSelectAll, sender);
}
}
}

Expand Down Expand Up @@ -335,8 +352,6 @@ public static void SetIsClearTextButtonBehaviorEnabled(Button obj, bool value)
obj.SetValue(IsClearTextButtonBehaviorEnabledProperty, value);
}



public static ICommand GetButtonCommand(DependencyObject d)
{
return (ICommand)d.GetValue(ButtonCommandProperty);
Expand Down Expand Up @@ -444,22 +459,22 @@ private static void ButtonCommandOrClearTextChanged(DependencyObject d, Dependen
if (textbox != null)
{
// only one loaded event
textbox.Loaded -= TextBoxLoaded;
textbox.Loaded += TextBoxLoaded;
textbox.Loaded -= TextChanged;
textbox.Loaded += TextChanged;
if (textbox.IsLoaded)
{
TextBoxLoaded(textbox, new RoutedEventArgs());
TextChanged(textbox, new RoutedEventArgs());
}
}
var passbox = d as PasswordBox;
if (passbox != null)
{
// only one loaded event
passbox.Loaded -= PassBoxLoaded;
passbox.Loaded += PassBoxLoaded;
passbox.Loaded -= PasswordChanged;
passbox.Loaded += PasswordChanged;
if (passbox.IsLoaded)
{
PassBoxLoaded(passbox, new RoutedEventArgs());
PasswordChanged(passbox, new RoutedEventArgs());
}
}
var combobox = d as ComboBox;
Expand All @@ -483,23 +498,5 @@ static void ComboBoxLoaded(object sender, RoutedEventArgs e)
comboBox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(comboBox.Text) || comboBox.SelectedItem != null);
}
}

static void PassBoxLoaded(object sender, RoutedEventArgs e)
{
var passbox = sender as PasswordBox;
if (passbox != null)
{
passbox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(passbox.Password));
}
}

static void TextBoxLoaded(object sender, RoutedEventArgs e)
{
var textbox = sender as TextBox;
if (textbox != null)
{
textbox.SetValue(HasTextProperty, !string.IsNullOrWhiteSpace(textbox.Text));
}
}
}
}
44 changes: 37 additions & 7 deletions MahApps.Metro/Controls/NumericUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace MahApps.Metro.Controls
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
Expand Down Expand Up @@ -157,7 +158,9 @@ private static void InterceptManualEnterChangedCallback(DependencyObject depende
typeof(bool),
typeof(NumericUpDown),
new FrameworkPropertyMetadata(true, OnHasDecimalsChanged));


private static readonly Regex RegexStringFormatHexadecimal = new Regex(@"^(?<complexHEX>.*{\d:X\d+}.*)?(?<simpleHEX>X\d+)?$", RegexOptions.Compiled);

private const double DefaultInterval = 1d;
private const int DefaultDelay = 500;
private const string ElementNumericDown = "PART_NumericDown";
Expand Down Expand Up @@ -855,6 +858,7 @@ private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChang
var numericUpDown = (NumericUpDown)d;

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

numericUpDown.CoerceValue(ValueProperty);
numericUpDown.CoerceValue(MaximumProperty);
numericUpDown.Value = (double?)CoerceValue(numericUpDown, numericUpDown.Value);
numericUpDown.OnMinimumChanged((double)e.OldValue, (double)e.NewValue);
numericUpDown.EnableDisableUpDown();
}
Expand All @@ -886,6 +891,7 @@ private static void OnStringFormatChanged(DependencyObject d, DependencyProperty
{
nud.InternalSetText(nud.Value);
}
nud.HasDecimals = !RegexStringFormatHexadecimal.IsMatch((string)e.NewValue);
}

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Expand Down Expand Up @@ -924,14 +930,9 @@ private void InternalSetText(double? newValue)
{
_valueTextBox.Text = newValue.Value.ToString(culture);
}
else if (!StringFormat.Contains("{"))
{
// then we may have a StringFormat of e.g. "N0"
_valueTextBox.Text = newValue.Value.ToString(StringFormat, culture);
}
else
{
_valueTextBox.Text = string.Format(culture, StringFormat, newValue.Value);
FormatValue(newValue, culture);
}

if ((bool)GetValue(TextBoxHelper.IsMonitoringProperty))
Expand All @@ -940,6 +941,35 @@ private void InternalSetText(double? newValue)
}
}

private void FormatValue(double? newValue, CultureInfo culture)
{
var match = RegexStringFormatHexadecimal.Match(StringFormat);
if (match.Success)
{
if (match.Groups["simpleHEX"].Success)
{
// HEX DOES SUPPORT INT ONLY.
_valueTextBox.Text = ((int)newValue.Value).ToString(match.Groups["simpleHEX"].Value, culture);
}
else if (match.Groups["complexHEX"].Success)
{
_valueTextBox.Text = string.Format(culture, match.Groups["complexHEX"].Value, (int)newValue.Value);
}
}
else
{
if (!StringFormat.Contains("{"))
{
// then we may have a StringFormat of e.g. "N0"
_valueTextBox.Text = newValue.Value.ToString(StringFormat, culture);
}
else
{
_valueTextBox.Text = string.Format(culture, StringFormat, newValue.Value);
}
}
}

private ScrollViewer TryFindScrollViewer()
{
_valueTextBox.ApplyTemplate();
Expand Down
66 changes: 64 additions & 2 deletions MahApps.Metro/Themes/NumericUpDown.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:converters="clr-namespace:MahApps.Metro.Converters">

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Shared.xaml" />
</ResourceDictionary.MergedDictionaries>

<converters:ThicknessToDoubleConverter x:Key="ThicknessToDoubleConverter" />
Expand Down Expand Up @@ -68,8 +68,31 @@
<ColumnDefinition x:Name="PART_NumericDownColumn"
Width="Auto" />
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="PART_FloatingMessageContainer"
Grid.Column="0"
Height="0"
IsHitTestVisible="False"
Margin="5,0"
Visibility="Visible">
<TextBlock x:Name="PART_FloatingMessage"
Text="{TemplateBinding Controls:TextBoxHelper.Watermark}"
FontSize="{DynamicResource FloatingWatermarkFontSize}"
Foreground="{TemplateBinding Foreground}"
Opacity="0.6"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<TextBlock.RenderTransform>
<TranslateTransform />
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
<TextBox x:Name="PART_TextBox"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xxMUROxx can you change the floating message part like in 1919458 ?
thx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@punker76 do you mean removing PART_FloatingMessage

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xxMUROxx no, i mean changeing Grid -> ContentControl and the tirgger part

1919458#diff-e09aa3d83a4c174f3c72c7698ff3c40eR124

1919458#diff-e09aa3d83a4c174f3c72c7698ff3c40eR193

Grid.Row="1"
Grid.Column="0"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Controls:ControlsHelper.DisabledVisualElementVisibility="Collapsed"
Expand All @@ -94,6 +117,7 @@
Controls:TextBoxHelper.ButtonsAlignment="{TemplateBinding ButtonsAlignment}" />
<RepeatButton x:Name="PART_NumericUp"
Grid.Column="1"
Grid.RowSpan="2"
Margin="2,2,0,2"
Delay="{TemplateBinding Delay}"
Foreground="{TemplateBinding Foreground}"
Expand All @@ -109,6 +133,7 @@
</RepeatButton>
<RepeatButton x:Name="PART_NumericDown"
Grid.Column="2"
Grid.RowSpan="2"
Margin="0,2,2,2"
VerticalContentAlignment="Center"
Delay="{TemplateBinding Delay}"
Expand All @@ -134,6 +159,36 @@
Opacity="0" />
</Grid>
<ControlTemplate.Triggers>
<!--Sets the MiniMessage visibility (Watermark must not be "" and FloatWatermark must be true)-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Controls:TextBoxHelper.HasText)}"
Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HideFloatingMessageStoryboard}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ShowFloatingMessageStoryboard}" />
</DataTrigger.ExitActions>
</DataTrigger>
<!--To override Watermark == ""-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Controls:TextBoxHelper.Watermark)}"
Value="">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HideFloatingMessageStoryboard}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ShowFloatingMessageStoryboard}" />
</DataTrigger.ExitActions>
</DataTrigger>
<!--To override TextBoxHelper.UseFloatingWatermark == false-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Controls:TextBoxHelper.UseFloatingWatermark)}"
Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HideFloatingMessageStoryboard}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ShowFloatingMessageStoryboard}" />
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="ButtonsAlignment"
Value="Left">
<Setter TargetName="PART_TextBox"
Expand Down Expand Up @@ -234,7 +289,14 @@
<Setter TargetName="Base"
Property="BorderBrush"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Controls:ControlsHelper.FocusBorderBrush)}" />
<Setter TargetName="PART_FloatingMessage"
Property="Foreground"
Value="{DynamicResource AccentColorBrush}" />
<Setter TargetName="PART_FloatingMessage"
Property="Opacity"
Value="1" />
</Trigger>


<Trigger Property="HideUpDownButtons"
Value="True">
Expand Down
3 changes: 2 additions & 1 deletion samples/MetroDemo/ExampleViews/TextExamples.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
Speedup="false" />
<Controls:NumericUpDown Margin="{StaticResource ControlMargin}"
Controls:TextBoxHelper.Watermark="Speedup when long pressed after 500ms"
Controls:TextBoxHelper.UseFloatingWatermark="True"
HasDecimals="{Binding ElementName=HasDecimalsCheckBox, Path=IsChecked, Mode=TwoWay}"
IsReadOnly="{Binding ElementName=ReadOnlyCheck, Path=IsChecked, Mode=TwoWay}"
Delay="500"
Expand All @@ -272,7 +273,7 @@
<TextBox Grid.Column="1"
Controls:TextBoxHelper.ClearTextButton="True"
VerticalAlignment="Center"
Text="{Binding ElementName=StringFormatNumUpDown, Path=StringFormat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}" />
Text="{Binding ElementName=StringFormatNumUpDown, Path=StringFormat, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True}" />
</Grid>
<Grid Margin="{StaticResource ControlMargin}">
<Grid.ColumnDefinitions>
Expand Down