• WPF自定义控件三:消息提示框


    需求:实现全局消息提示框

    一:创建全局Message

    public class Message
        {
            private static readonly Style infoStyle = (Style)Application.Current.Resources["InfoMessage"];
            private static readonly Style warningStyle = (Style)Application.Current.Resources["WarningMessage"];
            private static readonly Style successStyle = (Style)Application.Current.Resources["SuccessMessage"];
            private static readonly Style errorStyle = (Style)Application.Current.Resources["ErrorMessage"];
    
            #region 全局
            public static void Show(MessageType type, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                if (millisecondTimeOut <= 0)
                {
                    isClearable = true;
                }
    
                MessageWindow messageWindow = MessageWindow.GetInstance();
                messageWindow.Dispatcher.VerifyAccess();
    
                MessageCard messageCard;
                switch (type)
                {
                    default:
                    case MessageType.None:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable
                        };
                        break;
                    case MessageType.Info:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = infoStyle
                        };
                        break;
                    case MessageType.Warning:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = warningStyle
                        };
                        break;
                    case MessageType.Success:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = successStyle
                        };
                        break;
                    case MessageType.Error:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = errorStyle
                        };
                        break;
                }
    
                messageWindow.AddMessageCard(messageCard, millisecondTimeOut);
                messageWindow.Show();
            }
    
            public static void Show(UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.None, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowInfo(UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Info, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowSuccess(UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Success, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowWarning(UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Warning, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowError(UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Error, element, millisecondTimeOut, isClearable);
            }
    
            public static void Show(MessageType type, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(type, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void Show(string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.None, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowInfo(string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Info, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowSuccess(string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Success, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowWarning(string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Warning, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowError(string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(MessageType.Error, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
            #endregion
    
    
            #region 指定容器
            public static void Show(string containerIdentifier, MessageType type, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                if (!MessageContainer.Containers.ContainsKey(containerIdentifier))
                {
                    return;
                }
    
                if (millisecondTimeOut <= 0)
                {
                    isClearable = true;
                }
    
                Panel messagePanel = MessageContainer.Containers[containerIdentifier];
                messagePanel.Dispatcher.VerifyAccess();
    
                MessageCard messageCard;
                switch (type)
                {
                    default:
                    case MessageType.None:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable
                        };
                        break;
                    case MessageType.Info:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = infoStyle
                        };
                        break;
                    case MessageType.Warning:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = warningStyle
                        };
                        break;
                    case MessageType.Success:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = successStyle
                        };
                        break;
                    case MessageType.Error:
                        messageCard = new MessageCard
                        {
                            Content = element,
                            IsClearable = isClearable,
                            Style = errorStyle
                        };
                        break;
                }
    
                messagePanel.Children.Add(messageCard);
    
                // 进入动画
                Storyboard enterStoryboard = new Storyboard();
    
                DoubleAnimation opacityAnimation = new DoubleAnimation
                {
                    From = 0,
                    To = 1,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(UIElement.OpacityProperty));
    
                DoubleAnimation transformAnimation = new DoubleAnimation
                {
                    From = -30,
                    To = Application.Current.MainWindow.Height / 2-100,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(transformAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
    
                enterStoryboard.Children.Add(opacityAnimation);
                enterStoryboard.Children.Add(transformAnimation);
                if (millisecondTimeOut > 0)
                {
                    // 进入动画完成
                    enterStoryboard.Completed += async (sender, e) =>
                    {
                        await Task.Run(() =>
                        {
                            Thread.Sleep(millisecondTimeOut);
                        });
    
                        messagePanel.Children.Remove(messageCard);
                    };
    
                }
    
                messageCard.BeginStoryboard(enterStoryboard);
                // 退出动画
                //Storyboard exitStoryboard = new Storyboard();
    
                //DoubleAnimation exitOpacityAnimation = new DoubleAnimation
                //{
                //    From = 1,
                //    To = Application.Current.MainWindow.Height / 2,
                //    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                //    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                //};
                //Storyboard.SetTargetProperty(exitOpacityAnimation, new PropertyPath(UIElement.OpacityProperty));
    
                //DoubleAnimation exitTransformAnimation = new DoubleAnimation
                //{
                //    From = 0,
                //    To = -30,
                //    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                //    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                //};
                //Storyboard.SetTargetProperty(exitTransformAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
    
                //exitStoryboard.Children.Add(exitOpacityAnimation);
                //exitStoryboard.Children.Add(exitTransformAnimation);
    
                //if (millisecondTimeOut > 0)
                //{
                //    // 进入动画完成
                //    enterStoryboard.Completed += async (sender, e) =>
                //    {
                //        await Task.Run(() =>
                //        {
                //            Thread.Sleep(millisecondTimeOut);
                //        });
    
                //        messageCard.BeginStoryboard(exitStoryboard);
                //    };
    
                //}
    
                // 退出动画完成
                //exitStoryboard.Completed += (sender, e) =>
                //{
                //    messagePanel.Children.Remove(messageCard);
                //};
    
                //messageCard.BeginStoryboard(enterStoryboard);
            }
    
            public static void Show(string containerIdentifier, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.None, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowInfo(string containerIdentifier, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Info, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowSuccess(string containerIdentifier, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Success, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowWarning(string containerIdentifier, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Warning, element, millisecondTimeOut, isClearable);
            }
    
            public static void ShowError(string containerIdentifier, UIElement element, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Error, element, millisecondTimeOut, isClearable);
            }
    
            public static void Show(string containerIdentifier, MessageType type, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, type, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void Show(string containerIdentifier, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.None, new TextBlock { Text = message }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowInfo(string containerIdentifier, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Info, new TextBlock { Text = message, Foreground = new SolidColorBrush(Colors.White) }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowSuccess(string containerIdentifier, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Success, new TextBlock { Text = message, Foreground = new SolidColorBrush(Colors.White) }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowWarning(string containerIdentifier, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Warning, new TextBlock { Text = message, Foreground = new SolidColorBrush(Colors.White) }, millisecondTimeOut, isClearable);
            }
    
            public static void ShowError(string containerIdentifier, string message, int millisecondTimeOut = 3000, bool isClearable = true)
            {
                Show(containerIdentifier, MessageType.Error, new TextBlock { Text = message, Foreground = new SolidColorBrush(Colors.White) }, millisecondTimeOut, isClearable);
            }
            #endregion
        }
    
        public enum MessageType
        {
            None = 0,
            Info,
            Success,
            Warning,
            Error
        }
    

    二:创建消息提示控件

    1:创建名为MessageCard资源字典与MessageCard类

      <LinearGradientBrush x:Key="GridBackGrounds1" EndPoint="0,1" StartPoint="0,0">
            <GradientStop Color="#FF061118" Offset="0.191"/>
            <GradientStop Color="#FF173A52" Offset="1"/>
        </LinearGradientBrush>
    
    <Style x:Key="MessageCard" TargetType="{x:Type local:MessageCard}">
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="BorderBrush" Value="{StaticResource BorderGray}"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="CornerRadius" Value="2.5"/>
            <Setter Property="Background" Value="{DynamicResource GridBackGrounds1}"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="ThemeColorBrush" Value="{DynamicResource DefaultForeground}"/>
            <Setter Property="Margin" Value="2.5"/>
            <Setter Property="Padding" Value="5"/>
            <Setter Property="MinHeight" Value="60"/>
            <Setter Property="MinWidth" Value="200"/>
            <Setter Property="IsShwoIcon" Value="False"/>
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <TranslateTransform />
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:MessageCard}">
                        <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding ThemeColorBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}" Margin="{TemplateBinding Margin}"
                                CornerRadius="{TemplateBinding CornerRadius}">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding ThemeColorBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}" Effect="{StaticResource AllDirectionEffect}"
                                        Padding="{TemplateBinding Padding}" CornerRadius="{TemplateBinding CornerRadius}" 
                                        Grid.ColumnSpan="3"/>
    
                               
                                <ContentPresenter x:Name="contentPresenter" Focusable="False" Grid.Column="1"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              RecognizesAccessKey="True"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="8 0"/>
                                <Button x:Name="clearButton"  Foreground="{TemplateBinding ThemeColorBrush}"  
                                        Grid.Column="2" Style="{x:Null}" Height="20" BorderThickness="0" BorderBrush="Transparent" Background="Transparent" 
    local:ButtonHelper.ButtonStyle="Link" Visibility="{TemplateBinding IsClearable,Converter={StaticResource boolToVisibility}}"
    Content="X"
    > </Button> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="WarningMessage" TargetType="{x:Type local:MessageCard}" BasedOn="{StaticResource MessageCard}"> <Setter Property="ThemeColorBrush" Value="{StaticResource WarningBrush}"/> <Setter Property="IconType" Value="ErrorWarningFill"/>//IOC提示类型 <Setter Property="IsShwoIcon" Value="True"/> </Style> <Style x:Key="SuccessMessage" TargetType="{x:Type local:MessageCard}" BasedOn="{StaticResource MessageCard}"> <Setter Property="ThemeColorBrush" Value="{StaticResource SuccessBrush}"/> <Setter Property="IconType" Value="CheckboxCircleFill"/> <Setter Property="IsShwoIcon" Value="True"/> </Style> <Style x:Key="ErrorMessage" TargetType="{x:Type local:MessageCard}" BasedOn="{StaticResource MessageCard}"> <Setter Property="ThemeColorBrush" Value="{StaticResource ErrorBrush}"/> <Setter Property="IconType" Value="CloseCircleFill"/> <Setter Property="IsShwoIcon" Value="True"/> </Style> <Style x:Key="InfoMessage" TargetType="{x:Type local:MessageCard}" BasedOn="{StaticResource MessageCard}"> <Setter Property="ThemeColorBrush" Value="{StaticResource InfoBrush}"/> <Setter Property="IconType" Value="InformationFill"/> <Setter Property="IsShwoIcon" Value="True"/> </Style>
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using Zt.UI.Silver.Utils;
    
    namespace Zt.UI.Silver
    {
        public class MessageCard : ContentControl
        {
            public static readonly RoutedEvent CloseEvent;
    
            static MessageCard()
            {
                CloseEvent = EventManager.RegisterRoutedEvent("Close", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MessageCard));
                DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageCard), new FrameworkPropertyMetadata(typeof(MessageCard)));
            }
    
            #region 事件
            // 关闭消息事件
            public event RoutedEventHandler Close
            {
                add { base.AddHandler(MessageCard.CloseEvent, value); }
                remove { base.RemoveHandler(MessageCard.CloseEvent, value); }
            }
            #endregion
    
            #region 依赖属性
            public static readonly DependencyProperty CornerRadiusProperty =
              DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(MessageCard), new PropertyMetadata(default(CornerRadius)));
    
            public CornerRadius CornerRadius
            {
                get { return (CornerRadius)GetValue(CornerRadiusProperty); }
                set { SetValue(CornerRadiusProperty, value); }
            }
    
    
            public static readonly DependencyProperty ThemeColorBrushProperty =
                DependencyProperty.Register("ThemeColorBrush", typeof(SolidColorBrush), typeof(MessageCard), new PropertyMetadata(default(SolidColorBrush)));
    
            public SolidColorBrush ThemeColorBrush
            {
                get { return (SolidColorBrush)GetValue(ThemeColorBrushProperty); }
                set { SetValue(ThemeColorBrushProperty, value); }
            }
    
    
            public static readonly DependencyProperty IconTypeProperty =
                DependencyProperty.Register("IconType", typeof(IconType), typeof(MessageCard), new PropertyMetadata(default(IconType)));
    
            public IconType IconType
            {
                get { return (IconType)GetValue(IconTypeProperty); }
                set { SetValue(IconTypeProperty, value); }
            }
    
    
            public static readonly DependencyProperty IsShwoIconProperty =
                DependencyProperty.Register("IsShwoIcon", typeof(bool), typeof(MessageCard), new PropertyMetadata(default(bool)));
    
            public bool IsShwoIcon
            {
                get { return (bool)GetValue(IsShwoIconProperty); }
                set { SetValue(IsShwoIconProperty, value); }
            }
    
    
            public static readonly DependencyProperty IsClearableProperty =
                DependencyProperty.Register("IsClearable", typeof(bool), typeof(MessageCard), new PropertyMetadata(default(bool), OnIsClearbleChanged));
    
            public bool IsClearable
            {
                get { return (bool)GetValue(IsClearableProperty); }
                set { SetValue(IsClearableProperty, value); }
            }
    
            private static void OnIsClearbleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if (d is MessageCard messageCard)
                {
                    RoutedEventHandler handle = (sender, args) =>
                    {
                        if (VisualTreeHelper.GetParent(messageCard) is Panel panel)
                        {
                            // 退出动画
                            Storyboard exitStoryboard = new Storyboard();
    
                            DoubleAnimation exitOpacityAnimation = new DoubleAnimation
                            {
                                From = 1,
                                To = 0,
                                Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                            };
                            Storyboard.SetTargetProperty(exitOpacityAnimation, new PropertyPath(FrameworkElement.OpacityProperty));
    
                            DoubleAnimation exitTransformAnimation = new DoubleAnimation
                            {
                                From = 0,
                                To = -30,
                                Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                            };
                            Storyboard.SetTargetProperty(exitTransformAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
    
                            exitStoryboard.Children.Add(exitOpacityAnimation);
                            exitStoryboard.Children.Add(exitTransformAnimation);
    
                            // 动画完成
                            exitStoryboard.Completed += (a, b) =>
                            {
                                panel.Children.Remove(messageCard);
                                RoutedEventArgs eventArgs = new RoutedEventArgs(MessageCard.CloseEvent, messageCard);
                                messageCard.RaiseEvent(eventArgs);
                            };
    
                            messageCard.BeginStoryboard(exitStoryboard);    // 执行动画
                        }
                    };
                    messageCard.Foreground =new SolidColorBrush( Colors.Black);
                    messageCard.Loaded += (sender, arg) =>
                    {
                        if (messageCard.Template.FindName("clearButton", messageCard) is Button clearButton)
                        {
                            if (messageCard.IsClearable)
                            {
                                clearButton.Click += handle;
                            }
                            else
                            {
                                clearButton.Click -= handle;
                            }
                        }
                    };
    
                    messageCard.Unloaded += (sender, arg) =>
                    {
                        if (messageCard.Template.FindName("clearButton", messageCard) is Button clearButton)
                        {
                            if (messageCard.IsClearable)
                            {
                                clearButton.Click -= handle;
                            }
                        }
                    };
                }
            }
            #endregion
    
    
        }
    }

    2:创建名为MessageWindow的窗体

    <Window x:Class="Zt.UI.Silver.MessageWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Zt.UI.Silver"
            mc:Ignorable="d"
            Background="Transparent" WindowStyle="None" AllowsTransparency="True" WindowState="Maximized"
            ShowInTaskbar="False" WindowStartupLocation="CenterOwner" VerticalAlignment="Top" Topmost="True">
    
        <StackPanel x:Name="messageStackPanel" Margin="10">
    
        </StackPanel>
    </Window>

    后台代码:

     public partial class MessageWindow : Window
        {
            private static MessageWindow messageWindow = null;
    
            private MessageWindow()
            {
                InitializeComponent();
            }
    
            public static MessageWindow GetInstance()
            {
                if (messageWindow == null)
                {
                    messageWindow = new MessageWindow();
                }
                else if (!messageWindow.IsLoaded)
                {
                    messageWindow = new MessageWindow();
                }
                return messageWindow;
            }
    
            public void AddMessageCard(MessageCard messageCard, int millisecondTimeOut)
            {
                messageCard.Close += MessageCard_Close;
    
                messageStackPanel.Children.Add(messageCard);
    
                // 进入动画
                Storyboard enterStoryboard = new Storyboard();
    
                DoubleAnimation opacityAnimation = new DoubleAnimation
                {
                    From = 0,
                    To = 1,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(OpacityProperty));
    
                DoubleAnimation transformAnimation = new DoubleAnimation
                {
                    From = -30,
                    To = 0,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(transformAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
    
                enterStoryboard.Children.Add(opacityAnimation);
                enterStoryboard.Children.Add(transformAnimation);
    
                // 退出动画
                Storyboard exitStoryboard = new Storyboard();
    
                DoubleAnimation exitOpacityAnimation = new DoubleAnimation
                {
                    From = 1,
                    To = 0,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(exitOpacityAnimation, new PropertyPath(OpacityProperty));
    
                DoubleAnimation exitTransformAnimation = new DoubleAnimation
                {
                    From = 0,
                    To = -30,
                    Duration = new Duration(TimeSpan.FromMilliseconds(300)),
                    EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }
                };
                Storyboard.SetTargetProperty(exitTransformAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
    
                exitStoryboard.Children.Add(exitOpacityAnimation);
                exitStoryboard.Children.Add(exitTransformAnimation);
    
                // 进入动画完成
                if (millisecondTimeOut > 0)
                {
                    enterStoryboard.Completed += async (sender, e) =>
                    {
                        await Task.Run(() =>
                        {
                            Thread.Sleep(millisecondTimeOut);
                        });
    
                        Dispatcher.Invoke(() =>
                        {
                            messageCard.BeginStoryboard(exitStoryboard);
                        });
                    };
                }
    
                // 退出动画完成
                exitStoryboard.Completed += (sender, e) =>
                {
                    Dispatcher.Invoke(() =>
                    {
                        messageStackPanel.Children.Remove(messageCard);
                        if (messageStackPanel.Children.Count == 0)
                        {
                            this.Close();
                        }
                    });
                };
    
                messageCard.BeginStoryboard(enterStoryboard);
            }
    
            /// <summary>
            /// 消息卡片关闭按钮事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void MessageCard_Close(object sender, RoutedEventArgs e)
            {
                if (messageStackPanel.Children.Count == 0)
                {
                    this.Close();
                }
            }
        }

    三:添加转换器BoolToVisibilityConverter

     public class BoolToVisibilityConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if ((bool)value)
                {
                    return Visibility.Visible;
                }
                else
                {
                    return Visibility.Collapsed;
                }
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return DependencyProperty.UnsetValue;
            }
        }
    

      

    四:用法

    APP引用

     <ResourceDictionary Source="pack://application:,,,/Zt.UI.Silver;component/Themes/MessageCard.xaml" />
      <Style TargetType="{x:Type local:MessageCard}" BasedOn="{StaticResource MessageCard}"/>

    Main 下使用   

    <zt:MessageContainer Identifier="MessageContainer" Grid.RowSpan="10"/>

    CS:后台代码

    局部提示 Message.ShowError("MessageContainer","123",1000);
    全局提示 Message.ShowError("123",1000);

    五:演示

  • 相关阅读:
    使用对象-关系映射持久化数据
    Spring中使用JDBC
    无法正确解析FreeMarker视图
    使用Java配置SpringMVC
    面向切面的Spring
    高级装配
    爬虫简介与request模块
    列表存储本质以及索引为什么从0开始
    列表和字典操作的时间复杂度
    记录腾讯云中矿机病毒处理过程(重装系统了fu*k)
  • 原文地址:https://www.cnblogs.com/zt199510/p/14510575.html
Copyright © 2020-2023  润新知