forked from MahApps/MahApps.Metro
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ValidationErrorTemplate.xaml
148 lines (137 loc) · 9.13 KB
/
ValidationErrorTemplate.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="clr-namespace:MahApps.Metro.Controls">
<Style x:Key="MetroValidationPopup" TargetType="{x:Type mah:CustomValidationPopup}">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="HorizontalOffset" Value="0" />
<Setter Property="Placement" Value="Right" />
<Setter Property="PopupAnimation" Value="Fade" />
<Setter Property="VerticalOffset" Value="0" />
</Style>
<ControlTemplate x:Key="ValidationErrorTemplate">
<AdornedElementPlaceholder x:Name="placeholder">
<Grid SnapsToDevicePixels="True">
<Rectangle x:Name="PopupTargetElement"
Margin="-5 0 -5 0"
DataContext="{Binding ElementName=placeholder}"
StrokeThickness="0" />
<Border x:Name="ValidationErrorElement"
BorderBrush="{DynamicResource ControlsValidationBrush}"
BorderThickness="1"
DataContext="{Binding ElementName=placeholder}">
<Grid x:Name="RedTriangle"
Width="12"
Height="12"
Margin="1 -4 -4 0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="Transparent">
<Path Margin="1 3 0 0"
Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z"
Fill="{DynamicResource ValidationBrush5}" />
<Path Margin="1 3 0 0"
Data="M 0,0 L2,0 L 8,6 L8,8"
Fill="{DynamicResource WhiteColorBrush}" />
</Grid>
</Border>
<mah:CustomValidationPopup x:Name="ValidationPopup"
AllowsTransparency="True"
IsOpen="False"
PlacementTarget="{Binding ElementName=PopupTargetElement, Mode=OneWay}">
<Grid x:Name="Root" Margin="4">
<Grid.Resources>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Root, Path=IsMouseOver, Mode=OneWay}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0.15"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Border Margin="4 4 -4 -4"
Background="{DynamicResource ValidationBrush1}"
CornerRadius="5" />
<Border Margin="3 3 -3 -3"
Background="{DynamicResource ValidationBrush2}"
CornerRadius="4" />
<Border Margin="2 2 -2 -2"
Background="{DynamicResource ValidationBrush3}"
CornerRadius="3" />
<Border Margin="1 1 -1 -1"
Background="{DynamicResource ValidationBrush4}"
CornerRadius="2" />
<Border Background="{DynamicResource ValidationBrush5}" CornerRadius="2">
<!--
from Josh Smith
Binding to (Validation.Errors)[0] without Creating Debug Spew
http://joshsmithonwpf.wordpress.com/2008/10/08/binding-to-validationerrors0-without-creating-debug-spew/
The trick is to bind a ContentPresenter’s Content to the CurrentItem of Validation.Errors for the target element.
Binding to the CurrentItem means that we’re binding to the CurrentItem property of the default ICollectionView
that wraps the ReadOnlyObservableCollection<ValidationError> returned by the attached Errors property.
When the current item is non-null, that means there is a validation error; when it is null, there are no validation errors.
We can rely on ICollectionView to safely access the validation error, or not return anything if there are no errors.
That is what prevents the debug spew from pouring out.
The DataTemplate declared in the StackPanel’s Resources knows how to render a ValidationError object.
If the ContentPresenter has a null value, the template is not used to render anything.
Issue #707
-->
<Border.Resources>
<DataTemplate DataType="{x:Type ValidationError}">
<TextBlock MaxWidth="250"
Margin="8 4 8 4"
Foreground="{DynamicResource ValidationTextBrush}"
Text="{Binding ErrorContent}"
TextWrapping="Wrap"
UseLayoutRounding="False" />
</DataTemplate>
</Border.Resources>
<ItemsControl ItemsSource="{Binding}" />
</Border>
</Grid>
</mah:CustomValidationPopup>
</Grid>
</AdornedElementPlaceholder>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.IsKeyboardFocusWithin, Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.HasError), Mode=OneWay}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="ValidationPopup" Property="IsOpen" Value="True" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=RedTriangle, Path=IsMouseOver, Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.HasError), Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.(mah:ValidationHelper.ShowValidationErrorOnMouseOver), Mode=OneWay}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="ValidationPopup" Property="IsOpen" Value="True" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=RedTriangle, Path=IsMouseOver, Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=placeholder, Path=AdornedElement.(Validation.HasError), Mode=OneWay}" Value="True" />
<Condition Binding="{Binding ElementName=ValidationPopup, Path=ShowValidationErrorOnMouseOver, Mode=OneWay}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="ValidationPopup" Property="IsOpen" Value="True" />
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ResourceDictionary>