效果展示:
在网上那版的基础上做的后台样式拓展,使其不依赖样式模板。网上那版太多出处,我就不贴链接了。
下面是装饰器代码类。样式主要在这上面修改,图标用到了控件库,可使用原生图标替换即可
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);