WPF在MVVM模式下的消息提示功能。

效果展示:

在网上那版的基础上做的后台样式拓展,使其不依赖样式模板。网上那版太多出处,我就不贴链接了。

下面是装饰器代码类。样式主要在这上面修改,图标用到了控件库,可使用原生图标替换即可

public class MessageAdorner : Adorner
{
    private ListBox listBox;
    private UIElement _child;
    private FrameworkElement adornedElement;
    public MessageAdorner(UIElement adornedElement) : base(adornedElement)
    {
        this.adornedElement = adornedElement as FrameworkElement;
    }

    public void PushMessage(string message, int msgtype, int outTime)
    {
        if (listBox == null)
        {
            listBox = new ListBox() { Style = null, BorderThickness = new Thickness(0), Background = Brushes.Transparent };
            listBox.IsHitTestVisible = false;
            Child = listBox;
        }

        Border border = new Border();
        border.CornerRadius = new CornerRadius(10);
        border.BorderThickness = new Thickness(0);

        border.Opacity = 0.8;

        StackPanel panel = new StackPanel();
        panel.Orientation = Orientation.Horizontal;
        panel.MaxWidth = 300;

        PackIcon icon = new PackIcon();

        icon.Padding = new Thickness(2);
        icon.Margin = new Thickness(2);
        icon.MaxWidth = 100;
        icon.VerticalAlignment = VerticalAlignment.Center;
        icon.HorizontalAlignment = HorizontalAlignment.Center;
        panel.Children.Add(icon);


        TextBlock textBlock = new TextBlock();
        textBlock.Text = message;
        textBlock.TextWrapping = TextWrapping.Wrap;
        textBlock.Padding = new Thickness(2);
        textBlock.Margin = new Thickness(2);
        textBlock.MaxWidth = 200;
        textBlock.VerticalAlignment = VerticalAlignment.Center;
        textBlock.HorizontalAlignment = HorizontalAlignment.Center;
        panel.Children.Add(textBlock);
        border.Child = panel;

        if (msgtype == 0)
        {
            border.Background = Brushes.LightGreen;
            icon.Kind = PackIconKind.Check;
            //textBlock.Foreground=Brushes.Green;
        }
        if (msgtype == 1)
        {
            border.Background = Brushes.Yellow;
            icon.Kind = PackIconKind.Alert;
            //textBlock.Foreground = Brushes.Yellow;
        }
        if (msgtype == 2)
        {
            border.Background = Brushes.Red;
            icon.Kind = PackIconKind.Close;
            //textBlock.Foreground = Brushes.Red;
        }


        var item = new MessageItem { Content = border };

        var timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(outTime);
        timer.Tick += (sender, e) =>
        {
            listBox.Items.Remove(item);
            timer.Stop();
        };
        listBox.Items.Insert(0, item);
        timer.Start();
    }

    public UIElement Child
    {
        get => _child;
        set
        {
            if (value == null)
            {
                RemoveVisualChild(_child);
                _child = value;
                return;
            }
            AddVisualChild(value);
            _child = value;
        }
    }
    protected override int VisualChildrenCount
    {
        get
        {
            return _child != null ? 1 : 0;
        }
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        var x = (adornedElement.ActualWidth - _child.DesiredSize.Width) / 2;
        _child.Arrange(new Rect(new Point(x, 20), _child.DesiredSize));
        return finalSize;
    }

    protected override Visual GetVisualChild(int index)
    {
        if (index == 0 && _child != null) return _child;
        return base.GetVisualChild(index);
    }
}

下面是其他两个类:

 public class MessageItem : ListBoxItem
 {
     public MessageBoxImage MessageType
     {
         get { return (MessageBoxImage)GetValue(MessageTypeProperty); }
         set { SetValue(MessageTypeProperty, value); }
     }
     public static readonly DependencyProperty MessageTypeProperty =
         DependencyProperty.Register("MessageType", typeof(MessageBoxImage), typeof(MessageItem), new PropertyMetadata(MessageBoxImage.Information));


 }
 public static class Msg
 {
     private static MessageAdorner messageAdorner;
     /// <summary>
     /// 消息弹出
     /// </summary>
     /// <param name="message">消息内容</param>
     /// <param name="msgtype">消息类型;0正常,1警告,2错误</param>
     /// <param name="outTime">自动关闭时间。默认5秒</param>
     /// <exception cref="Exception"></exception>
     public static void MsgShow(string message, int msgtype, int outTime = 5)
     {
         if (messageAdorner != null)
         {
             messageAdorner.PushMessage(message, msgtype, outTime);
             return;
         }
         Window win = null;
         if (Application.Current.Windows.Count > 0)
         {
             win = Application.Current.Windows.OfType<Window>().FirstOrDefault(o => o.IsActive);
             if (win == null)
                 win = Application.Current.Windows.OfType<Window>().First(o => o.IsActive);
         }

         var layer = GetAdornerLayer(win);
         if (layer == null)
             throw new Exception("not AdornerLayer is null");
         messageAdorner = new MessageAdorner(layer);
         layer.Add(messageAdorner);
         messageAdorner.PushMessage(message, msgtype, outTime);
     }
     static AdornerLayer GetAdornerLayer(Visual visual)
     {
         var decorator = visual as AdornerDecorator;
         if (decorator != null)
             return decorator.AdornerLayer;
         var presenter = visual as ScrollContentPresenter;
         if (presenter != null)
             return presenter.AdornerLayer;
         var visualContent = (visual as Window)?.Content as Visual;
         return AdornerLayer.GetAdornerLayer(visualContent ?? visual);
     }
 }

使用方法:Msg.MsgShow("哇!你真是太棒啦!", 0,5);

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值