WPF 中的验证错误样式,类似于 Silverlight [英] Validation Error Style in WPF, similar to Silverlight

查看:28
本文介绍了WPF 中的验证错误样式,类似于 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?

如果有人想尝试一下,上面的验证错误可以用下面的代码重现,适用于 SilverlightWPF

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,但在我完成它后,我注意到它可能很烦人,因为它在移动鼠标.让我知道我是否应该删除它.. :)

我使用带有 BooleanOrConverterMultiBinding 来在 TextBox 具有键盘焦点或鼠标结束时显示工具提示错误"右上角.对于淡入动画,我使用 DoubleAnimation 作为 OpacityThicknessAnimationBackEase/>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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆