Skip to content

Commit cb08b95

Browse files
Propagate HintAssist.Background into TimePicker and DatePicker (#3367)
* Add failing UI tests * Fix failing tests * Reset launchSettings.json back to "Home"
1 parent 6d1ea72 commit cb08b95

File tree

7 files changed

+191
-7
lines changed

7 files changed

+191
-7
lines changed

MainDemo.Wpf/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"profiles": {
33
"Demo App": {
44
"commandName": "Project",
5-
"commandLineArgs": "-p Trees -t Inherit -f LeftToRight"
5+
"commandLineArgs": "-p Home -t Inherit -f LeftToRight"
66
}
77
}
88
}

MaterialDesignThemes.UITests/WPF/DatePickers/DatePickerTests.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel;
22
using System.Globalization;
3+
using System.Windows.Media;
34
using MaterialDesignThemes.UITests.WPF.TextBoxes;
45

56
namespace MaterialDesignThemes.UITests.WPF.DatePickers;
@@ -232,6 +233,74 @@ public async Task DatePicker_WithHintAndValidationError_RespectsPadding(string s
232233

233234
recorder.Success();
234235
}
236+
237+
[Fact]
238+
[Description("Issue 3365")]
239+
public async Task DatePicker_WithoutOutlinedStyleAndNoCustomHintBackgroundSet_ShouldApplyDefaultBackgroundWhenFloated()
240+
{
241+
await using var recorder = new TestRecorder(App);
242+
243+
// Arrange
244+
var stackPanel = await LoadXaml<StackPanel>("""
245+
<StackPanel>
246+
<DatePicker
247+
Style="{StaticResource MaterialDesignOutlinedDatePicker}"
248+
materialDesign:HintAssist.Hint="Hint text" />
249+
</StackPanel>
250+
""");
251+
var datePicker = await stackPanel.GetElement<DatePicker>("/DatePicker");
252+
var datePickerTextBox = await datePicker.GetElement<DatePickerTextBox>("/DatePickerTextBox");
253+
var hintBackgroundBorder = await datePicker.GetElement<Border>("HintBackgroundBorder");
254+
255+
var defaultBackground = Colors.Transparent;
256+
var defaultFloatedBackground = await GetThemeColor("MaterialDesign.Brush.Background");
257+
258+
// Assert (unfocused state)
259+
Assert.Equal(defaultBackground, await hintBackgroundBorder.GetBackgroundColor());
260+
261+
// Act
262+
await datePickerTextBox.MoveKeyboardFocus();
263+
264+
// Assert (focused state)
265+
Assert.Equal(defaultFloatedBackground, await hintBackgroundBorder.GetBackgroundColor());
266+
267+
recorder.Success();
268+
}
269+
270+
[Theory]
271+
[Description("Issue 3365")]
272+
[InlineData("MaterialDesignDatePicker")]
273+
[InlineData("MaterialDesignFloatingHintDatePicker")]
274+
[InlineData("MaterialDesignFilledDatePicker")]
275+
[InlineData("MaterialDesignOutlinedDatePicker")]
276+
public async Task DatePicker_WithCustomHintBackgroundSet_ShouldApplyHintBackground(string style)
277+
{
278+
await using var recorder = new TestRecorder(App);
279+
280+
// Arrange
281+
var stackPanel = await LoadXaml<StackPanel>($$"""
282+
<StackPanel>
283+
<DatePicker
284+
Style="{StaticResource {{style}}}"
285+
materialDesign:HintAssist.Hint="Hint text"
286+
materialDesign:HintAssist.Background="Red" />
287+
</StackPanel>
288+
""");
289+
var datePicker = await stackPanel.GetElement<DatePicker>("/DatePicker");
290+
var datePickerTextBox = await datePicker.GetElement<DatePickerTextBox>("/DatePickerTextBox");
291+
var hintBackgroundBorder = await datePicker.GetElement<Border>("HintBackgroundBorder");
292+
293+
// Assert (unfocused state)
294+
Assert.Equal(Colors.Red, await hintBackgroundBorder.GetBackgroundColor());
295+
296+
// Act
297+
await datePickerTextBox.MoveKeyboardFocus();
298+
299+
// Assert (focused state)
300+
Assert.Equal(Colors.Red, await hintBackgroundBorder.GetBackgroundColor());
301+
302+
recorder.Success();
303+
}
235304
}
236305

237306
public class FutureDateValidationRule : ValidationRule

MaterialDesignThemes.UITests/WPF/TimePickers/TimePickerTests.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.ComponentModel;
22
using System.Globalization;
3+
using System.Windows.Media;
34
using MaterialDesignThemes.UITests.WPF.TextBoxes;
45

56
namespace MaterialDesignThemes.UITests.WPF.TimePickers;
@@ -539,6 +540,74 @@ public async Task TimePicker_WithClearButton_ClearButtonClearsUncommittedText()
539540

540541
recorder.Success();
541542
}
543+
544+
[Fact]
545+
[Description("Issue 3365")]
546+
public async Task TimePicker_WithoutOutlinedStyleAndNoCustomHintBackgroundSet_ShouldApplyDefaultBackgroundWhenFloated()
547+
{
548+
await using var recorder = new TestRecorder(App);
549+
550+
// Arrange
551+
var stackPanel = await LoadXaml<StackPanel>("""
552+
<StackPanel>
553+
<materialDesign:TimePicker
554+
Style="{StaticResource MaterialDesignOutlinedTimePicker}"
555+
materialDesign:HintAssist.Hint="Hint text" />
556+
</StackPanel>
557+
""");
558+
var timePicker = await stackPanel.GetElement<TimePicker>("/TimePicker");
559+
var timePickerTextBox = await timePicker.GetElement<TimePickerTextBox>("/TimePickerTextBox");
560+
var hintBackgroundBorder = await timePicker.GetElement<Border>("HintBackgroundBorder");
561+
562+
var defaultBackground = Colors.Transparent;
563+
var defaultFloatedBackground = await GetThemeColor("MaterialDesign.Brush.Background");
564+
565+
// Assert (unfocused state)
566+
Assert.Equal(defaultBackground, await hintBackgroundBorder.GetBackgroundColor());
567+
568+
// Act
569+
await timePickerTextBox.MoveKeyboardFocus();
570+
571+
// Assert (focused state)
572+
Assert.Equal(defaultFloatedBackground, await hintBackgroundBorder.GetBackgroundColor());
573+
574+
recorder.Success();
575+
}
576+
577+
[Theory]
578+
[Description("Issue 3365")]
579+
[InlineData("MaterialDesignTimePicker")]
580+
[InlineData("MaterialDesignFloatingHintTimePicker")]
581+
[InlineData("MaterialDesignFilledTimePicker")]
582+
[InlineData("MaterialDesignOutlinedTimePicker")]
583+
public async Task TimePicker_WithCustomHintBackgroundSet_ShouldApplyHintBackground(string style)
584+
{
585+
await using var recorder = new TestRecorder(App);
586+
587+
// Arrange
588+
var stackPanel = await LoadXaml<StackPanel>($$"""
589+
<StackPanel>
590+
<materialDesign:TimePicker
591+
Style="{StaticResource {{style}}}"
592+
materialDesign:HintAssist.Hint="Hint text"
593+
materialDesign:HintAssist.Background="Red" />
594+
</StackPanel>
595+
""");
596+
var timePicker = await stackPanel.GetElement<TimePicker>("/TimePicker");
597+
var timePickerTextBox = await timePicker.GetElement<TimePickerTextBox>("/TimePickerTextBox");
598+
var hintBackgroundBorder = await timePicker.GetElement<Border>("HintBackgroundBorder");
599+
600+
// Assert (unfocused state)
601+
Assert.Equal(Colors.Red, await hintBackgroundBorder.GetBackgroundColor());
602+
603+
// Act
604+
await timePickerTextBox.MoveKeyboardFocus();
605+
606+
// Assert (focused state)
607+
Assert.Equal(Colors.Red, await hintBackgroundBorder.GetBackgroundColor());
608+
609+
recorder.Success();
610+
}
542611
}
543612

544613
public class OnlyTenOClockValidationRule : ValidationRule
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Globalization;
2+
using System.Windows.Data;
3+
using System.Windows.Media;
4+
5+
namespace MaterialDesignThemes.Wpf.Converters;
6+
7+
public class OutlinedStyleFloatingHintBackgroundConverter : IMultiValueConverter
8+
{
9+
public object? Convert(object[]? values, Type targetType, object? parameter, CultureInfo culture)
10+
{
11+
if (values is { Length: 2 } &&
12+
values[0] is Brush hintAssistBrush &&
13+
values[1] is Brush defaultBackgroundBrush)
14+
{
15+
return Equals(HintAssist.DefaultBackground, hintAssistBrush) ? defaultBackgroundBrush : hintAssistBrush;
16+
}
17+
return Binding.DoNothing;
18+
}
19+
20+
public object[]? ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture)
21+
=> throw new NotImplementedException();
22+
}

MaterialDesignThemes.Wpf/HintAssist.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public static class HintAssist
77
private const double DefaultFloatingScale = 0.74;
88
private const double DefaultHintOpacity = 0.56;
99
internal static readonly Point DefaultFloatingOffset = new(0, -16);
10-
private static readonly Brush DefaultBackground = new SolidColorBrush(Colors.Transparent);
10+
internal static readonly Brush DefaultBackground = new SolidColorBrush(Colors.Transparent);
1111
private static readonly double DefaultHelperTextFontSize = 10;
1212

1313
#region AttachedProperty : IsFloatingProperty

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.DatePicker.xaml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
<converters:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
3333

3434
<Style x:Key="MaterialDesignDatePickerTextBox" TargetType="{x:Type DatePickerTextBox}">
35+
<Style.Resources>
36+
<converters:OutlinedStyleFloatingHintBackgroundConverter x:Key="OutlinedStyleFloatingHintBackgroundConverter" />
37+
</Style.Resources>
3538
<Setter Property="AllowDrop" Value="true" />
3639
<Setter Property="Background" Value="Transparent" />
3740
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.ForegroundLight}" />
@@ -190,7 +193,8 @@
190193
<wpf:SmartHint.Hint>
191194
<Border x:Name="HintBackgroundBorder"
192195
Background="{TemplateBinding wpf:HintAssist.Background}"
193-
CornerRadius="2">
196+
CornerRadius="2"
197+
Tag="{DynamicResource MaterialDesign.Brush.Background}">
194198
<ContentPresenter x:Name="HintWrapper" Content="{TemplateBinding wpf:HintAssist.Hint}" />
195199
</Border>
196200
</wpf:SmartHint.Hint>
@@ -322,7 +326,14 @@
322326
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
323327
<Condition SourceName="Hint" Property="IsHintInFloatingPosition" Value="True" />
324328
</MultiTrigger.Conditions>
325-
<Setter Property="wpf:HintAssist.Background" Value="{DynamicResource MaterialDesign.Brush.Background}" />
329+
<Setter TargetName="HintBackgroundBorder" Property="Background">
330+
<Setter.Value>
331+
<MultiBinding Converter="{StaticResource OutlinedStyleFloatingHintBackgroundConverter}">
332+
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="(wpf:HintAssist.Background)" />
333+
<Binding ElementName="HintBackgroundBorder" Path="Tag" />
334+
</MultiBinding>
335+
</Setter.Value>
336+
</Setter>
326337
<Setter TargetName="HintBackgroundBorder" Property="Padding" Value="4,0" />
327338
</MultiTrigger>
328339
<MultiTrigger>
@@ -519,6 +530,7 @@
519530
wpf:HintAssist.FloatingScale="{TemplateBinding wpf:HintAssist.FloatingScale}"
520531
wpf:HintAssist.FontFamily="{TemplateBinding wpf:HintAssist.FontFamily}"
521532
wpf:HintAssist.Foreground="{TemplateBinding wpf:HintAssist.Foreground}"
533+
wpf:HintAssist.Background="{TemplateBinding wpf:HintAssist.Background}"
522534
wpf:HintAssist.HelperText="{TemplateBinding wpf:HintAssist.HelperText}"
523535
wpf:HintAssist.HelperTextFontSize="{TemplateBinding wpf:HintAssist.HelperTextFontSize}"
524536
wpf:HintAssist.HelperTextStyle="{TemplateBinding wpf:HintAssist.HelperTextStyle}"

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.TimePicker.xaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
1+
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
22
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
33
xmlns:converters="clr-namespace:MaterialDesignThemes.Wpf.Converters"
44
xmlns:internal="clr-namespace:MaterialDesignThemes.Wpf.Internal"
@@ -30,6 +30,9 @@
3030
<converters:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
3131

3232
<Style x:Key="MaterialDesignTimePickerTextBox" TargetType="{x:Type wpf:TimePickerTextBox}">
33+
<Style.Resources>
34+
<converters:OutlinedStyleFloatingHintBackgroundConverter x:Key="OutlinedStyleFloatingHintBackgroundConverter" />
35+
</Style.Resources>
3336
<Setter Property="AllowDrop" Value="true" />
3437
<Setter Property="Background" Value="Transparent" />
3538
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesign.Brush.ForegroundLight}" />
@@ -188,7 +191,8 @@
188191
<wpf:SmartHint.Hint>
189192
<Border x:Name="HintBackgroundBorder"
190193
Background="{TemplateBinding wpf:HintAssist.Background}"
191-
CornerRadius="2">
194+
CornerRadius="2"
195+
Tag="{DynamicResource MaterialDesign.Brush.Background}">
192196
<ContentPresenter x:Name="HintWrapper" Content="{TemplateBinding wpf:HintAssist.Hint}" />
193197
</Border>
194198
</wpf:SmartHint.Hint>
@@ -320,7 +324,14 @@
320324
<Condition Property="wpf:HintAssist.IsFloating" Value="True" />
321325
<Condition SourceName="Hint" Property="IsHintInFloatingPosition" Value="True" />
322326
</MultiTrigger.Conditions>
323-
<Setter Property="wpf:HintAssist.Background" Value="{DynamicResource MaterialDesign.Brush.Background}" />
327+
<Setter TargetName="HintBackgroundBorder" Property="Background">
328+
<Setter.Value>
329+
<MultiBinding Converter="{StaticResource OutlinedStyleFloatingHintBackgroundConverter}">
330+
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="(wpf:HintAssist.Background)" />
331+
<Binding ElementName="HintBackgroundBorder" Path="Tag" />
332+
</MultiBinding>
333+
</Setter.Value>
334+
</Setter>
324335
<Setter TargetName="HintBackgroundBorder" Property="Padding" Value="4,0" />
325336
</MultiTrigger>
326337
<MultiTrigger>
@@ -531,6 +542,7 @@
531542
wpf:HintAssist.FloatingScale="{TemplateBinding wpf:HintAssist.FloatingScale}"
532543
wpf:HintAssist.FontFamily="{TemplateBinding wpf:HintAssist.FontFamily}"
533544
wpf:HintAssist.Foreground="{TemplateBinding wpf:HintAssist.Foreground}"
545+
wpf:HintAssist.Background="{TemplateBinding wpf:HintAssist.Background}"
534546
wpf:HintAssist.HelperText="{TemplateBinding wpf:HintAssist.HelperText}"
535547
wpf:HintAssist.HelperTextFontSize="{TemplateBinding wpf:HintAssist.HelperTextFontSize}"
536548
wpf:HintAssist.HelperTextStyle="{TemplateBinding wpf:HintAssist.HelperTextStyle}"

0 commit comments

Comments
 (0)