WPF 中的验证错误样式,类似于 Silverlight [英] Validation Error Style in WPF, similar to Silverlight
问题描述
默认情况下,WPF 中的 Validation.ErrorTemplate
只是一个小的红色边框,没有任何 ToolTip
.
By default, the Validation.ErrorTemplate
in WPF is just a small red border without any ToolTip
.
在 Silverlight 4 中,验证错误的样式很好地开箱即用.
In Silverlight 4, the validation error is nicely styled out-of-the-box.
这是 Silverlight 4 和 WPF 中发生的验证错误的比较
Here is a comparison of a validation error occuring in Silverlight 4 and WPF
银光 4
WPF
请注意,与在我看来 Silverlight 中的出色外观相比,WPF 版本的外观非常平淡乏味.
Notice the really flat, boring look of the WPF version compared to the, in my opinion, great look in Silverlight.
WPF 框架中是否存在任何类似的验证样式/模板,或者是否有人创建了样式精美的验证模板,例如上面的 Silverlight 版本?还是我必须从头开始创建它们?
Does any similar validation styles/templates exist in the WPF Framework or has anybody created nicely styled validation templates like the Silverlight version above? Or will I have to create them from scratch?
如果有人想尝试一下,上面的验证错误可以用下面的代码重现,适用于 Silverlight 和 WPF
If anybody wants to try it out, the validation error above can be reproduced with the following code, works for both Silverlight and WPF
MainWindow/MainPage.xaml
<StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top">
<TextBox Text="{Binding Path=TextProperty, Mode=TwoWay, ValidatesOnExceptions=True}"/>
<Button Content="Tab To Me..." Margin="20,0,0,0"/>
</StackPanel>
MainWindow/MainPage.xaml.cs
public MainWindow/MainPage()
{
InitializeComponent();
this.DataContext = this;
}
private string _textProperty;
public string TextProperty
{
get { return _textProperty; }
set
{
if (value.Length > 5)
{
throw new Exception("Too many characters");
}
_textProperty = value;
}
}
推荐答案
我研究了验证错误模板的 Silverlight 版本并创建了它的 WPF 版本,它看起来像像这样
I studied the Silverlight version of the Validation Error Template and created a WPF version of it which looks like this
在帖子底部添加了一个动画 GIF,但在我完成它后,我注意到它可能很烦人,因为它在移动鼠标.让我知道我是否应该删除它.. :)
我使用带有 BooleanOrConverter
的 MultiBinding
来在 TextBox
具有键盘焦点或鼠标结束时显示工具提示错误"右上角.对于淡入动画,我使用 DoubleAnimation
作为 Opacity
和 ThicknessAnimation
和 BackEase
/>EaseOut
EasingFunction
用于 Margin
I used a MultiBinding
with a BooleanOrConverter
to show the "tooltip-error" when the TextBox
has Keyboard focus or the Mouse is over the upper right corner. For the fade-in animation I used a DoubleAnimation
for the Opacity
and a ThicknessAnimation
with a BackEase
/EaseOut
EasingFunction
for the Margin
可以这样使用
<TextBox Validation.ErrorTemplate="{StaticResource errorTemplateSilverlightStyle}" />
errorTemplateSilverlightStyle
<ControlTemplate x:Key="errorTemplateSilverlightStyle">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="#FFdc000c" CornerRadius="0.7"
VerticalAlignment="Top">
<Grid>
<Polygon x:Name="toolTipCorner"
Grid.ZIndex="2"
Margin="-1"
Points="6,6 6,0 0,0"
Fill="#FFdc000c"
HorizontalAlignment="Right"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<Polyline Grid.ZIndex="3"
Points="7,7 0,0" Margin="-1" HorizontalAlignment="Right"
StrokeThickness="1.5"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
Stroke="White"
VerticalAlignment="Top"
IsHitTestVisible="True"/>
<AdornedElementPlaceholder x:Name="adorner"/>
</Grid>
</Border>
<Border x:Name="errorBorder" Background="#FFdc000c" Margin="1,0,0,0"
Opacity="0" CornerRadius="1.5"
IsHitTestVisible="False"
MinHeight="24" MaxWidth="267">
<Border.Effect>
<DropShadowEffect ShadowDepth="2.25"
Color="Black"
Opacity="0.4"
Direction="315"
BlurRadius="4"/>
</Border.Effect>
<TextBlock Text="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White" Margin="8,3,8,3" TextWrapping="Wrap"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BooleanOrConverter}">
<Binding ElementName="adorner" Path="AdornedElement.IsKeyboardFocused" />
<Binding ElementName="toolTipCorner" Path="IsMouseOver"/>
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="fadeInStoryboard">
<Storyboard>
<DoubleAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="1"/>
<ThicknessAnimation Duration="00:00:00.15"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Margin"
FillBehavior="HoldEnd"
From="1,0,0,0"
To="5,0,0,0">
<ThicknessAnimation.EasingFunction>
<BackEase EasingMode="EaseOut" Amplitude="2"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="fadeInStoryboard"/>
<BeginStoryboard x:Name="fadeOutStoryBoard">
<Storyboard>
<DoubleAnimation Duration="00:00:00"
Storyboard.TargetName="errorBorder"
Storyboard.TargetProperty="Opacity"
To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
BooleanOrConverter
public class BooleanOrConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
foreach (object value in values)
{
if ((bool)value == true)
{
return true;
}
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
这篇关于WPF 中的验证错误样式,类似于 Silverlight的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!