Skip to content

Commit f98ff3b

Browse files
committed
Merge branch 'mdFieldStyle' of https://github.com/JeffBarnard/MaterialDesignInXamlToolkit into JeffBarnard-mdFieldStyle
2 parents 41403ea + 5966cd0 commit f98ff3b

9 files changed

+109
-30
lines changed

MaterialDesignThemes.Wpf/HintProxyFabric.ComboBox.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public ComboBoxHintProxy(ComboBox comboBox)
2626
_comboBox.SelectionChanged += ComboBoxSelectionChanged;
2727
_comboBox.Loaded += ComboBoxLoaded;
2828
_comboBox.IsVisibleChanged += ComboBoxIsVisibleChanged;
29+
_comboBox.IsKeyboardFocusWithinChanged += ComboBoxIsKeyboardFocusWithinChanged;
2930
}
3031

3132
public object Content
@@ -48,16 +49,16 @@ public object Content
4849

4950
public bool IsVisible => _comboBox.IsVisible;
5051

51-
public bool IsEmpty()
52-
{
53-
return string.IsNullOrEmpty(_comboBox.Text);
54-
}
52+
public bool IsEmpty() => string.IsNullOrEmpty(_comboBox.Text);
53+
54+
public bool IsFocused() => _comboBox.IsEditable && _comboBox.IsKeyboardFocusWithin;
5555

5656
public event EventHandler ContentChanged;
5757

5858
public event EventHandler IsVisibleChanged;
5959

6060
public event EventHandler Loaded;
61+
public event EventHandler FocusedChanged;
6162

6263
private void ComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
6364
{
@@ -79,12 +80,18 @@ private void ComboBoxTextChanged(object sender, TextChangedEventArgs e)
7980
ContentChanged?.Invoke(sender, EventArgs.Empty);
8081
}
8182

83+
private void ComboBoxIsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
84+
{
85+
FocusedChanged?.Invoke(sender, EventArgs.Empty);
86+
}
87+
8288
public void Dispose()
8389
{
8490
_comboBox.RemoveHandler(TextBoxBase.TextChangedEvent, _comboBoxTextChangedEventHandler);
8591
_comboBox.Loaded -= ComboBoxLoaded;
8692
_comboBox.IsVisibleChanged -= ComboBoxIsVisibleChanged;
87-
_comboBox.SelectionChanged -= ComboBoxSelectionChanged;
93+
_comboBox.SelectionChanged -= ComboBoxSelectionChanged;
94+
_comboBox.IsKeyboardFocusWithinChanged -= ComboBoxIsKeyboardFocusWithinChanged;
8895
}
8996
}
9097
}

MaterialDesignThemes.Wpf/HintProxyFabric.PasswordBox.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ private sealed class PasswordBoxHintProxy : IHintProxy
1717

1818
public bool IsVisible => _passwordBox.IsVisible;
1919

20+
public bool IsFocused() => _passwordBox.IsKeyboardFocused;
21+
2022
public event EventHandler ContentChanged;
2123
public event EventHandler IsVisibleChanged;
2224
public event EventHandler Loaded;
25+
public event EventHandler FocusedChanged;
2326

2427
public PasswordBoxHintProxy(PasswordBox passwordBox)
2528
{
@@ -29,6 +32,12 @@ public PasswordBoxHintProxy(PasswordBox passwordBox)
2932
_passwordBox.PasswordChanged += PasswordBoxPasswordChanged;
3033
_passwordBox.Loaded += PasswordBoxLoaded;
3134
_passwordBox.IsVisibleChanged += PasswordBoxIsVisibleChanged;
35+
_passwordBox.IsKeyboardFocusedChanged += PasswordBoxIsKeyboardFocusedChanged;
36+
}
37+
38+
private void PasswordBoxIsKeyboardFocusedChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
39+
{
40+
FocusedChanged?.Invoke(this, EventArgs.Empty);
3241
}
3342

3443
private void PasswordBoxIsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
@@ -51,6 +60,7 @@ public void Dispose()
5160
_passwordBox.PasswordChanged -= PasswordBoxPasswordChanged;
5261
_passwordBox.Loaded -= PasswordBoxLoaded;
5362
_passwordBox.IsVisibleChanged -= PasswordBoxIsVisibleChanged;
63+
_passwordBox.IsKeyboardFocusedChanged -= PasswordBoxIsKeyboardFocusedChanged;
5464
}
5565

5666
}

MaterialDesignThemes.Wpf/HintProxyFabric.TextBox.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ private sealed class TextBoxHintProxy : IHintProxy
1818

1919
public bool IsEmpty() => string.IsNullOrEmpty(_textBox.Text);
2020

21+
public bool IsFocused() => _textBox.IsKeyboardFocused;
22+
2123
public event EventHandler ContentChanged;
2224
public event EventHandler IsVisibleChanged;
2325
public event EventHandler Loaded;
26+
public event EventHandler FocusedChanged;
2427

2528
public TextBoxHintProxy(TextBox textBox)
2629
{
@@ -30,6 +33,12 @@ public TextBoxHintProxy(TextBox textBox)
3033
_textBox.TextChanged += TextBoxTextChanged;
3134
_textBox.Loaded += TextBoxLoaded;
3235
_textBox.IsVisibleChanged += TextBoxIsVisibleChanged;
36+
_textBox.IsKeyboardFocusedChanged += TextBoxIsKeyboardFocusedChanged;
37+
}
38+
39+
private void TextBoxIsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
40+
{
41+
FocusedChanged?.Invoke(sender, EventArgs.Empty);
3342
}
3443

3544
private void TextBoxIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
@@ -52,6 +61,7 @@ public void Dispose()
5261
_textBox.TextChanged -= TextBoxTextChanged;
5362
_textBox.Loaded -= TextBoxLoaded;
5463
_textBox.IsVisibleChanged -= TextBoxIsVisibleChanged;
64+
_textBox.IsKeyboardFocusedChanged -= TextBoxIsKeyboardFocusedChanged;
5565
}
5666
}
5767
}

MaterialDesignThemes.Wpf/IHintProxy.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ public interface IHintProxy : IDisposable
2121
/// <returns></returns>
2222
bool IsEmpty();
2323

24+
/// <summary>
25+
/// Targeted control has keyboard focus
26+
/// </summary>
27+
/// <returns></returns>
28+
bool IsFocused();
29+
2430
[Obsolete]
2531
object Content { get; }
2632

@@ -33,5 +39,7 @@ public interface IHintProxy : IDisposable
3339
event EventHandler IsVisibleChanged;
3440

3541
event EventHandler Loaded;
42+
43+
event EventHandler FocusedChanged;
3644
}
3745
}

MaterialDesignThemes.Wpf/SmartHint.cs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Threading.Tasks;
77
using System.Windows;
88
using System.Windows.Controls;
9-
using System.Windows.Media.Animation;
109
using MaterialDesignThemes.Wpf.Converters;
1110

1211
namespace MaterialDesignThemes.Wpf
@@ -19,13 +18,18 @@ namespace MaterialDesignThemes.Wpf
1918
/// </summary>
2019
[TemplateVisualState(GroupName = ContentStatesGroupName, Name = ContentEmptyName)]
2120
[TemplateVisualState(GroupName = ContentStatesGroupName, Name = ContentNotEmptyName)]
21+
[TemplateVisualState(GroupName = ContentStatesGroupName, Name = HintRestingPositionName)]
22+
[TemplateVisualState(GroupName = ContentStatesGroupName, Name = HintFloatingPositionName)]
2223
public class SmartHint : Control
2324
{
2425
public const string ContentStatesGroupName = "ContentStates";
26+
[System.Obsolete]
2527
public const string ContentEmptyName = "ContentEmpty";
28+
[System.Obsolete]
2629
public const string ContentNotEmptyName = "ContentNotEmpty";
2730

28-
private ContentControl _floatingHintPart = null;
31+
public const string HintRestingPositionName = "HintRestingPosition";
32+
public const string HintFloatingPositionName = "HintFloatingPosition";
2933

3034
#region ManagedProperty
3135

@@ -71,6 +75,24 @@ public bool IsContentNullOrEmpty
7175

7276
#endregion
7377

78+
#region IsHintInFloatingPosition
79+
80+
private static readonly DependencyPropertyKey IsHintInFloatingPositionPropertyKey =
81+
DependencyProperty.RegisterReadOnly(
82+
"IsHintInFloatingPosition", typeof(bool), typeof(SmartHint),
83+
new PropertyMetadata(default(bool)));
84+
85+
public static readonly DependencyProperty IsHintInFloatingPositionProperty =
86+
IsHintInFloatingPositionPropertyKey.DependencyProperty;
87+
88+
public bool IsHintInFloatingPosition
89+
{
90+
get { return (bool)GetValue(IsHintInFloatingPositionProperty); }
91+
private set { SetValue(IsHintInFloatingPositionPropertyKey, value); }
92+
}
93+
94+
#endregion
95+
7496
#region UseFloating
7597

7698
public static readonly DependencyProperty UseFloatingProperty = DependencyProperty.Register(
@@ -143,6 +165,7 @@ private static void HintProxyPropertyChangedCallback(DependencyObject dependency
143165
hintProxy.IsVisibleChanged -= smartHint.OnHintProxyIsVisibleChanged;
144166
hintProxy.ContentChanged -= smartHint.OnHintProxyContentChanged;
145167
hintProxy.Loaded -= smartHint.OnHintProxyContentChanged;
168+
hintProxy.FocusedChanged -= smartHint.OnHintProxyFocusedChanged;
146169
hintProxy.Dispose();
147170
}
148171

@@ -152,21 +175,26 @@ private static void HintProxyPropertyChangedCallback(DependencyObject dependency
152175
hintProxy.IsVisibleChanged += smartHint.OnHintProxyIsVisibleChanged;
153176
hintProxy.ContentChanged += smartHint.OnHintProxyContentChanged;
154177
hintProxy.Loaded += smartHint.OnHintProxyContentChanged;
178+
hintProxy.FocusedChanged += smartHint.OnHintProxyFocusedChanged;
155179
smartHint.RefreshState(false);
156180
}
157181

182+
protected virtual void OnHintProxyFocusedChanged(object sender, EventArgs e)
183+
{
184+
if (HintProxy.IsLoaded)
185+
RefreshState(true);
186+
else
187+
HintProxy.Loaded += HintProxySetStateOnLoaded;
188+
}
189+
158190
protected virtual void OnHintProxyContentChanged(object sender, EventArgs e)
159191
{
160192
IsContentNullOrEmpty = HintProxy.IsEmpty();
161193

162194
if (HintProxy.IsLoaded)
163-
{
164195
RefreshState(true);
165-
}
166-
else
167-
{
196+
else
168197
HintProxy.Loaded += HintProxySetStateOnLoaded;
169-
}
170198
}
171199

172200
private void HintProxySetStateOnLoaded(object sender, EventArgs e)
@@ -182,20 +210,26 @@ protected virtual void OnHintProxyIsVisibleChanged(object sender, EventArgs e)
182210

183211
private void RefreshState(bool useTransitions)
184212
{
185-
var proxy = HintProxy;
213+
IHintProxy proxy = HintProxy;
186214

187215
if (proxy == null) return;
188216
if (!proxy.IsVisible) return;
189217

190218
var action = new Action(() =>
191219
{
192-
var isEmpty = proxy.IsEmpty();
220+
string state = string.Empty;
193221

194-
var state = isEmpty
195-
? ContentEmptyName
196-
: ContentNotEmptyName;
197-
198-
VisualStateManager.GoToState(this, state, useTransitions);
222+
bool isEmpty = proxy.IsEmpty();
223+
bool isFocused = proxy.IsFocused();
224+
225+
if (UseFloating)
226+
state = !isEmpty || isFocused ? HintFloatingPositionName : HintRestingPositionName;
227+
else
228+
state = !isEmpty ? HintFloatingPositionName : HintRestingPositionName;
229+
230+
IsHintInFloatingPosition = state == HintFloatingPositionName;
231+
232+
VisualStateManager.GoToState(this, state, useTransitions);
199233
});
200234

201235
if (DesignerProperties.GetIsInDesignMode(this))

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ComboBox.xaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,17 @@
508508
<MultiTrigger>
509509
<MultiTrigger.Conditions>
510510
<Condition SourceName="Hint" Property="IsContentNullOrEmpty" Value="False" />
511-
<Condition Property="IsKeyboardFocused" Value="True" />
511+
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
512+
<Condition Property="IsKeyboardFocusWithin" Value="True" />
513+
</MultiTrigger.Conditions>
514+
<Setter TargetName="Hint" Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" />
515+
<Setter TargetName="Hint" Property="HintOpacity" Value="1" />
516+
</MultiTrigger>
517+
<MultiTrigger>
518+
<MultiTrigger.Conditions>
519+
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
520+
<Condition SourceName="Hint" Property="IsHintInFloatingPosition" Value="True" />
521+
<Condition Property="IsKeyboardFocusWithin" Value="True" />
512522
</MultiTrigger.Conditions>
513523
<Setter TargetName="Hint" Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" />
514524
<Setter TargetName="Hint" Property="HintOpacity" Value="1" />

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.PasswordBox.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
<ControlTemplate.Triggers>
6666
<MultiTrigger>
6767
<MultiTrigger.Conditions>
68-
<Condition SourceName="Hint" Property="IsContentNullOrEmpty" Value="False" />
68+
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
6969
<Condition Property="IsKeyboardFocused" Value="True" />
7070
</MultiTrigger.Conditions>
7171
<Setter TargetName="Hint" Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" />

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.SmartHint.xaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,27 @@
2626
<VisualStateManager.VisualStateGroups>
2727
<VisualStateGroup x:Name="ContentStates">
2828
<VisualStateGroup.Transitions>
29-
<VisualTransition From="*" To="ContentNotEmpty">
29+
<VisualTransition From="*" To="HintFloatingPosition">
3030
<Storyboard>
3131
<DoubleAnimation Storyboard.TargetName="SimpleHintTextBlock" Storyboard.TargetProperty="Opacity"
3232
Duration="0:0:0" To="0" />
3333
</Storyboard>
3434
</VisualTransition>
35-
<VisualTransition From="*" To="ContentEmpty">
35+
<VisualTransition From="*" To="HintRestingPosition">
3636
<Storyboard>
3737
<DoubleAnimation Storyboard.TargetName="SimpleHintTextBlock" Storyboard.TargetProperty="Opacity"
3838
Duration="0:0:0.3"
3939
EasingFunction="{StaticResource AnimationEasingFunction}"/>
4040
</Storyboard>
4141
</VisualTransition>
4242
</VisualStateGroup.Transitions>
43-
<VisualState x:Name="ContentNotEmpty">
43+
<VisualState x:Name="HintFloatingPosition">
4444
<Storyboard>
4545
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SimpleHintTextBlock"
4646
Duration="0" To="0" />
4747
</Storyboard>
4848
</VisualState>
49-
<VisualState x:Name="ContentEmpty">
49+
<VisualState x:Name="HintRestingPosition">
5050
<Storyboard>
5151
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SimpleHintTextBlock"
5252
Duration="0" />
@@ -78,7 +78,7 @@
7878
<VisualStateManager.VisualStateGroups>
7979
<VisualStateGroup x:Name="ContentStates">
8080
<VisualStateGroup.Transitions>
81-
<VisualTransition From="*" To="ContentNotEmpty">
81+
<VisualTransition From="*" To="HintFloatingPosition">
8282
<Storyboard>
8383
<DoubleAnimation Storyboard.TargetName="FloatingHintTextBlock" Storyboard.TargetProperty="Opacity"
8484
Duration="0:0:0.3" To="{TemplateBinding HintOpacity}"
@@ -88,7 +88,7 @@
8888
EasingFunction="{StaticResource AnimationEasingFunction}"/>
8989
</Storyboard>
9090
</VisualTransition>
91-
<VisualTransition From="*" To="ContentEmpty">
91+
<VisualTransition From="*" To="HintRestingPosition">
9292
<Storyboard>
9393
<DoubleAnimation Storyboard.TargetName="FloatingHintTextBlock" Storyboard.TargetProperty="Opacity"
9494
Duration="0:0:0.3"
@@ -99,15 +99,15 @@
9999
</Storyboard>
100100
</VisualTransition>
101101
</VisualStateGroup.Transitions>
102-
<VisualState x:Name="ContentNotEmpty">
102+
<VisualState x:Name="HintFloatingPosition">
103103
<Storyboard>
104104
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FloatingHintTextBlock"
105105
Duration="0" To="{TemplateBinding HintOpacity}" />
106106
<DoubleAnimation Storyboard.TargetName="ScaleHost" Storyboard.TargetProperty="Scale"
107107
Duration="0" To="1"/>
108108
</Storyboard>
109109
</VisualState>
110-
<VisualState x:Name="ContentEmpty">
110+
<VisualState x:Name="HintRestingPosition">
111111
<Storyboard>
112112
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FloatingHintTextBlock"
113113
Duration="0" />

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.TextBox.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
<ControlTemplate.Triggers>
9191
<MultiTrigger>
9292
<MultiTrigger.Conditions>
93-
<Condition SourceName="Hint" Property="IsContentNullOrEmpty" Value="False" />
93+
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
9494
<Condition Property="IsKeyboardFocused" Value="True" />
9595
</MultiTrigger.Conditions>
9696
<Setter TargetName="Hint" Property="Foreground" Value="{DynamicResource PrimaryHueMidBrush}" />

0 commit comments

Comments
 (0)