Skip to content

Commit 8dfc6c8

Browse files
committed
floating hints for text boxes
1 parent 7e0d58c commit 8dfc6c8

File tree

4 files changed

+157
-23
lines changed

4 files changed

+157
-23
lines changed

MaterialDesignColors.WpfExample/ProvingGround.xaml

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:system="clr-namespace:System;assembly=mscorlib"
7+
xmlns:wpf="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf"
78
x:Class="MaterialDesignColors.WpfExample.ProvingGround"
89
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
910
Background="{DynamicResource MaterialDesignPaper}"
1011
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
1112
mc:Ignorable="d"
12-
d:DesignWidth="340" d:DesignHeight="635">
13+
d:DesignWidth="680" d:DesignHeight="120">
1314
<UserControl.Resources>
1415
<ResourceDictionary>
1516
<ResourceDictionary.MergedDictionaries>
@@ -49,10 +50,10 @@
4950
<SolidColorBrush x:Key="SecondaryAccentForegroundBrush" Color="{StaticResource Accent700Foreground}"/>
5051
</ResourceDictionary>
5152
</ResourceDictionary.MergedDictionaries>
52-
5353

5454

55-
55+
56+
5657

5758

5859

@@ -61,11 +62,28 @@
6162
</UserControl.Resources>
6263

6364
<Grid>
64-
<StackPanel Margin="1.5,0,-1.5,0">
65-
<ProgressBar Value="25" Maximum="100" HorizontalAlignment="Stretch" Margin="24" />
66-
<ProgressBar Value="50" Maximum="100" HorizontalAlignment="Stretch" Margin="24" />
67-
<ProgressBar Value="75" Maximum="100" HorizontalAlignment="Stretch" Margin="24" />
68-
<ProgressBar IsIndeterminate="True" HorizontalAlignment="Stretch" Margin="24" />
65+
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" >
66+
<TextBox wpf:TextField.Hint="Type Stuff" Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
67+
VerticalAlignment="Bottom" Width="80" />
68+
<TextBox wpf:TextField.Hint="Type Stuff" Text="I did type stuff" Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
69+
VerticalAlignment="Bottom" Margin="24 0 0 0" Width="80" />
70+
<TextBox wpf:TextField.Hint="Big" Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
71+
VerticalAlignment="Bottom"
72+
FontSize="24" Margin="24 0 0 0" Width="80" />
73+
<TextBox wpf:TextField.Hint="Big" Text="Large!" Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
74+
FontSize="24" Margin="24 0 0 0" Width="80" />
75+
<ComboBox wpf:TextField.Hint="OS" VerticalAlignment="Bottom" Margin="24 0 0 0" Width="80">
76+
<ComboBoxItem>Andoid</ComboBoxItem>
77+
<ComboBoxItem>iOS</ComboBoxItem>
78+
<ComboBoxItem>Linux</ComboBoxItem>
79+
<ComboBoxItem>Windows</ComboBoxItem>
80+
</ComboBox>
81+
<ComboBox wpf:TextField.Hint="OS" SelectedIndex="2" VerticalAlignment="Bottom" Margin="24 0 0 0" Width="80">
82+
<ComboBoxItem>Andoid</ComboBoxItem>
83+
<ComboBoxItem>iOS</ComboBoxItem>
84+
<ComboBoxItem>Linux</ComboBoxItem>
85+
<ComboBoxItem>Windows</ComboBoxItem>
86+
</ComboBox>
6987
</StackPanel>
7088
</Grid>
7189

MaterialDesignColors.WpfExample/TextFields.xaml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
<UserControl.Resources>
1111
<ResourceDictionary>
1212
<ResourceDictionary.MergedDictionaries>
13-
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Slider.xaml" />
13+
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Slider.xaml" />
14+
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.TextBox.xaml" />
1415
</ResourceDictionary.MergedDictionaries>
1516
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MaterialDesignTextBox}">
1617
<Setter Property="HorizontalAlignment" Value="Stretch" />
@@ -42,6 +43,7 @@
4243
<Grid.RowDefinitions>
4344
<RowDefinition Height="Auto" />
4445
<RowDefinition Height="Auto" />
46+
<RowDefinition Height="Auto" />
4547
<RowDefinition Height="Auto" />
4648
<RowDefinition Height="Auto" />
4749
<RowDefinition Height="Auto" />
@@ -110,18 +112,20 @@
110112
<PasswordBox Grid.Row="2" Grid.Column="3"
111113
x:Name="PasswordBox"
112114
wpf:TextField.Hint="Password" />
113-
<DatePicker Grid.Row="3" Grid.Column="1" Width="100" HorizontalAlignment="Left" Margin="0 8 0 8"
115+
<TextBox Grid.Row="3" Grid.Column="1" wpf:TextField.Hint="Floating Hint" Style="{StaticResource MaterialDesignFloatingHintTextBox}" />
116+
<TextBox Grid.Row="3" Grid.Column="3" wpf:TextField.Hint="Floating Hint" Style="{StaticResource MaterialDesignFloatingHintTextBox}" Text="Good stuff" />
117+
<DatePicker Grid.Row="4" Grid.Column="1" Width="100" HorizontalAlignment="Left" Margin="0 8 0 8"
114118
wpf:TextField.Hint="James"/>
115-
<wpf:TimePicker Grid.Row="3" Grid.Column="3" VerticalAlignment="Top" Width="90" HorizontalAlignment="Left" Margin="0 8 0 8" />
116-
<wpf:TimePicker Grid.Row="3" Grid.Column="4" x:Name="PresetTimePicker" VerticalAlignment="Top" Width="90" HorizontalAlignment="Left" Margin="0 8 0 8"
119+
<wpf:TimePicker Grid.Row="4" Grid.Column="3" VerticalAlignment="Top" Width="90" HorizontalAlignment="Left" Margin="0 8 0 8" />
120+
<wpf:TimePicker Grid.Row="4" Grid.Column="4" x:Name="PresetTimePicker" VerticalAlignment="Top" Width="90" HorizontalAlignment="Left" Margin="0 8 0 8"
117121
wpf:TextField.Hint="Custom hint" />
118-
<Slider Grid.Row="4" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" Minimum="1" Maximum="50" Value="25" />
119-
<StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="3" Grid.RowSpan="3" >
122+
<Slider Grid.Row="5" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" Minimum="1" Maximum="50" Value="25" />
123+
<StackPanel Orientation="Horizontal" Grid.Row="5" Grid.Column="3" Grid.RowSpan="3" >
120124
<Slider TickFrequency="5" TickPlacement="BottomRight" Orientation="Vertical" Minimum="1" Maximum="50" />
121125
<Slider TickFrequency="25" TickPlacement="TopLeft" Orientation="Vertical" Minimum="1" Maximum="50" IsEnabled="False" Margin="24 8 0 8" />
122126
</StackPanel>
123-
<Slider Grid.Row="5" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" TickPlacement="BottomRight" Minimum="1" Maximum="50" Value="25" IsSelectionRangeEnabled="True" />
124-
<Slider Grid.Row="6" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" TickPlacement="BottomRight" Minimum="1" Maximum="50" Value="25" IsEnabled="False" />
125-
<TextBlock Grid.Row="7" Grid.Column="0" Margin="0 8 0 0">List</TextBlock>
127+
<Slider Grid.Row="6" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" TickPlacement="BottomRight" Minimum="1" Maximum="50" Value="25" IsSelectionRangeEnabled="True" />
128+
<Slider Grid.Row="7" Grid.Column="1" TickFrequency="5" Orientation="Horizontal" TickPlacement="BottomRight" Minimum="1" Maximum="50" Value="25" IsEnabled="False" />
129+
126130
</Grid>
127131
</UserControl>

MaterialDesignThemes.Wpf/TextField.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ public static class TextField
4040
typeof(TextField),
4141
new PropertyMetadata(.23, HintOpacityPropertyChangedCallback));
4242

43+
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached(
44+
"Text", typeof (string), typeof (TextField), new PropertyMetadata(default(string), TextPropertyChangedCallback));
45+
46+
47+
private static readonly DependencyPropertyKey IsNullOrEmptyPropertyKey = DependencyProperty.RegisterAttachedReadOnly(
48+
"IsNullOrEmpty", typeof(bool), typeof(TextField), new PropertyMetadata(true));
49+
50+
public static readonly DependencyProperty IsNullOrEmptyProperty =
51+
IsNullOrEmptyPropertyKey.DependencyProperty;
52+
4353
#endregion
4454

4555
#region Public Methods and Operators
@@ -110,6 +120,16 @@ public static void SetHintOpacity(DependencyObject element, double value)
110120
element.SetValue(HintOpacityProperty, value);
111121
}
112122

123+
public static void SetText(DependencyObject element, string value)
124+
{
125+
element.SetValue(TextProperty, value);
126+
}
127+
128+
public static string GetText(DependencyObject element)
129+
{
130+
return (string)element.GetValue(TextProperty);
131+
}
132+
113133
#endregion
114134

115135
#region Methods
@@ -185,7 +205,22 @@ private static void HintOpacityPropertyChangedCallback(
185205
}
186206

187207
textBoxBase.Opacity = (double)dependencyPropertyChangedEventArgs.NewValue;
188-
}
208+
}
209+
210+
private static void TextPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
211+
{
212+
SetIsNullOrEmpty(dependencyObject, string.IsNullOrEmpty((dependencyPropertyChangedEventArgs.NewValue ?? "").ToString()));
213+
}
214+
215+
private static void SetIsNullOrEmpty(DependencyObject element, bool value)
216+
{
217+
element.SetValue(IsNullOrEmptyPropertyKey, value);
218+
}
219+
220+
public static bool GetIsNullOrEmpty(DependencyObject element)
221+
{
222+
return (bool)element.GetValue(IsNullOrEmptyProperty);
223+
}
189224

190225
#endregion
191226
}

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.TextBox.xaml

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66
<converters:TextFieldHintVisibilityConverter x:Key="TextFieldHintVisibilityConverter" />
77

88
<Style x:Key="MaterialDesignTextBox" TargetType="{x:Type TextBox}">
9-
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
10-
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}" />
9+
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
10+
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}" />
1111
<Setter Property="BorderThickness" Value="0 0 0 1"/>
1212
<Setter Property="wpf:TextField.TextBoxViewMargin" Value="1 0 1 0" />
1313
<Setter Property="Background" Value="Transparent"/>
14-
<Setter Property="CaretBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=BorderBrush}"/>
14+
<Setter Property="CaretBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=BorderBrush}"/>
1515
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
1616
<Setter Property="HorizontalContentAlignment" Value="Left"/>
1717
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
1818
<Setter Property="AllowDrop" Value="true"/>
1919
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
20-
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
20+
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
2121
<Setter Property="Validation.ErrorTemplate">
2222
<Setter.Value>
2323
<ControlTemplate>
@@ -35,7 +35,7 @@
3535
Padding="0 4 0 4">
3636
<Grid>
3737
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
38-
/>
38+
/>
3939
<TextBlock Text="{Binding Path=(wpf:TextField.Hint), RelativeSource={RelativeSource TemplatedParent}}"
4040
Visibility="{TemplateBinding Text, Converter={StaticResource TextFieldHintVisibilityConverter}}"
4141
x:Name="Hint"
@@ -73,4 +73,81 @@
7373
</Style.Triggers>
7474
</Style>
7575

76+
<Style x:Key="MaterialDesignFloatingHintTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource MaterialDesignTextBox}">
77+
<Setter Property="wpf:TextField.Text" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
78+
<Setter Property="Template">
79+
<Setter.Value>
80+
<ControlTemplate TargetType="TextBox">
81+
<ControlTemplate.Resources>
82+
<Storyboard x:Key="MoveHintAsideStoryboard">
83+
<DoubleAnimation Storyboard.TargetProperty="FontSize" Storyboard.TargetName="Hint"
84+
Duration="0:0:0.3" To="10">
85+
<DoubleAnimation.EasingFunction>
86+
<SineEase EasingMode="EaseOut" />
87+
</DoubleAnimation.EasingFunction>
88+
</DoubleAnimation>
89+
<ThicknessAnimation Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="Hint"
90+
Duration="0:0:0.3" To="1,-16,1,0">
91+
<ThicknessAnimation.EasingFunction>
92+
<SineEase EasingMode="EaseOut" />
93+
</ThicknessAnimation.EasingFunction>
94+
</ThicknessAnimation>
95+
</Storyboard>
96+
<Storyboard x:Key="MoveHintBackStoryboard">
97+
<DoubleAnimation Storyboard.TargetProperty="FontSize" Storyboard.TargetName="Hint"
98+
Duration="0:0:0.3">
99+
<DoubleAnimation.EasingFunction>
100+
<SineEase EasingMode="EaseOut" />
101+
</DoubleAnimation.EasingFunction>
102+
</DoubleAnimation>
103+
<ThicknessAnimation Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="Hint"
104+
Duration="0:0:0.3">
105+
<ThicknessAnimation.EasingFunction>
106+
<SineEase EasingMode="EaseOut" />
107+
</ThicknessAnimation.EasingFunction>
108+
</ThicknessAnimation>
109+
</Storyboard>
110+
</ControlTemplate.Resources>
111+
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
112+
Padding="0 4 0 4">
113+
<Grid Margin="0 12 0 0">
114+
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
115+
/>
116+
<TextBlock Text="{Binding Path=(wpf:TextField.Hint), RelativeSource={RelativeSource TemplatedParent}}"
117+
FontSize="{TemplateBinding FontSize}"
118+
HorizontalAlignment="Left"
119+
x:Name="Hint"
120+
Margin="1 0 1 0"
121+
Opacity="{Binding Path=(wpf:TextField.HintOpacity), RelativeSource={RelativeSource TemplatedParent}}"/>
122+
</Grid>
123+
</Border>
124+
<ControlTemplate.Triggers>
125+
<Trigger Property="wpf:TextField.IsNullOrEmpty" Value="False">
126+
<Trigger.EnterActions>
127+
<BeginStoryboard x:Name="MoveHintAsideStoryboard_BeginStoryboard" Storyboard="{StaticResource MoveHintAsideStoryboard}"/>
128+
</Trigger.EnterActions>
129+
<Trigger.ExitActions>
130+
<BeginStoryboard x:Name="MoveHintBackStoryboard_BeginStoryboard" Storyboard="{StaticResource MoveHintBackStoryboard}"/>
131+
</Trigger.ExitActions>
132+
</Trigger>
133+
<Trigger Property="IsEnabled" Value="false">
134+
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
135+
</Trigger>
136+
<Trigger Property="IsMouseOver" Value="true">
137+
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryHueMidBrush}"/>
138+
</Trigger>
139+
<Trigger Property="IsKeyboardFocused" Value="true">
140+
<Setter TargetName="border" Property="Padding" Value="0 4 0 3"/>
141+
<Setter Property="BorderThickness" Value="0 0 0 2"/>
142+
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryHueMidBrush}"/>
143+
</Trigger>
144+
<Trigger Property="Validation.HasError" Value="true">
145+
<Setter Property="BorderBrush" Value="#f44336"/>
146+
</Trigger>
147+
</ControlTemplate.Triggers>
148+
</ControlTemplate>
149+
</Setter.Value>
150+
</Setter>
151+
</Style>
152+
76153
</ResourceDictionary>

0 commit comments

Comments
 (0)