WPF全局窗口错误提示框

来源:互联网 发布:淘宝直播里的东西好吗 编辑:程序博客网 时间:2024/06/05 03:03

不管是CS还是BS,在需要用户提交数据的页面上,总是要做一些校验,如果校验有错就要给用户提示,WPF里自然也避免不了这个问题。一开始,我是在窗口上预留了一个TextBlock,并且设置其Visibility=Collapsed,当校验有错的时候,再把这个TextBlock显示出来,这样做是可以实现既定需求,但是这样却会影响整个窗口的布局,以下图举个例子:
这里写图片描述
现在这个TextBlock隐藏在输入框和搜索按钮之间,大家知道Visibility=Collapsed是不占布局的,一旦我将Visibility设成了Visible,搜索按钮将会往下移动,这样的体验显然不好;有的同学要说了,那初始时设置Visibility=Hidden好了,这个是占布局的,这样按钮不会下移,的确,按钮是不会下移了,但是这里莫名其妙空白一块也是影响美观的吧。

我们平时见多了APP中或者H5中的页面中央一块黑色背景的提示,这种体验还是比较好的,那在WPF里也实现一个吧~
思路很简单,在每个窗口布局里最外层Grid里与内容快平级放置一个上下左右都居中的框就可以了,然后依照实际情况控制这个框的Visibility属性。显然,这样会有不少的工作量,尤其是项目里窗口比较多的时候。再想想,对,我们要搞一个窗口模板,让有需要的窗口使用这个模板就行了。
新建一个资源字典VcreditWindowWithAlert.xaml,代码如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    <ControlTemplate x:Key="CustomAlertWindowTemplete" TargetType="Window">              <Border BorderBrush="Transparent" BorderThickness="12" x:Name="outBorder">            <Border.Effect>                <DropShadowEffect BlurRadius="15" Color="#000000" Opacity=".25" Direction="90" ShadowDepth="1"/>            </Border.Effect>            <Grid Background="White">                <AdornerDecorator>                    <ContentPresenter></ContentPresenter>                </AdornerDecorator>                <Border x:Name="alertBorder" Visibility="Collapsed" Background="#82000000" CornerRadius="8" Padding="6" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="24" MaxWidth="300">                    <TextBlock x:Name="alertText"  TextWrapping="Wrap" Foreground="White" VerticalAlignment="Center"></TextBlock>                    <Border.Resources>                        <Storyboard x:Key="alertStoryboard">                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="alertBorder" Storyboard.TargetProperty="Visibility" Duration="0:0:4">                                <ObjectAnimationUsingKeyFrames.KeyFrames>                                    <DiscreteObjectKeyFrame KeyTime="0:0:0" >                                        <DiscreteObjectKeyFrame.Value>                                            <Visibility>Visible</Visibility>                                        </DiscreteObjectKeyFrame.Value>                                    </DiscreteObjectKeyFrame>                                    <DiscreteObjectKeyFrame KeyTime="0:0:4" >                                        <DiscreteObjectKeyFrame.Value>                                            <Visibility>Collapsed</Visibility>                                        </DiscreteObjectKeyFrame.Value>                                    </DiscreteObjectKeyFrame>                                </ObjectAnimationUsingKeyFrames.KeyFrames>                            </ObjectAnimationUsingKeyFrames>                        </Storyboard>                    </Border.Resources>                </Border>            </Grid>        </Border>    </ControlTemplate>    <Style x:Key="CustomAlertWindow" TargetType="Window">        <Setter Property="AllowsTransparency" Value="True"/>        <Setter Property="WindowStyle" Value="None"/>        <Setter Property="Template" Value="{StaticResource CustomAlertWindowTemplete}">     </Setter>    </Style></ResourceDictionary>

稍微解释一下上面代码,可以看到,还是在Grid里与ContentPresenter内容块平级放置了一个Border,这个Border里放置我们要显示的错误信息,并且我们通过一个动画5秒后自动关闭这个错误提示,另外还设置了Border的MaxWidth=”300”,是为了防止窗口较长时,这个Border会过分长。

那么,我们怎么使用上面这个模板呢,首先在App.xaml里要引入一下:

<ResourceDictionary Source="Resources/VcreditWindowWithAlert.xaml"/>

然后在需要使用的窗口里,通过Style属性引用模板:

Style="{StaticResource CustomAlertWindow}"

当需要提示错误的时候,我们通过代码找到那个动画,并且Begin它。以下是我写的一个通用方法,你可以在各个已经引入模板的窗口里调用它:

public static void ShowAlert(Window win, string msg){            ControlTemplate customWindowTemplate = App.Current.Resources["CustomAlertWindowTemplete"] as ControlTemplate;            if (customWindowTemplate!=null)            {                var border = customWindowTemplate.FindName("alertBorder",win) as Border;                if (border != null)                {                    var textblock = border.FindChild<TextBlock>("alertText");                    textblock.Text = msg;                    Storyboard sb = border.Resources["alertStoryboard"] as Storyboard;                    sb.Begin();                }            }}

这里有同学可能没有FindChild方法,这个方法是MahApps.Metro.dll里的,你当然没有必要为了这一个方法去引用这个dll,VisualTreeHelper什么的也是可以实现查找子元素父元素的。

上一下效果图:
这里写图片描述

原创粉丝点击