WPF规避空域问题的气泡弹窗
1.气泡消息接口
/// <summary>
/// 消息服务接口
/// </summary>
public interface IMessageBusService
{
/// <summary>
/// 显示错误信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
Task ShowErrorAsync(string message,double showDuration=3);
/// <summary>
/// 显示成功信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
Task ShowSuccessAsync(string message, double showDuration = 3);
/// <summary>
/// 显示警告信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
Task ShowWarnAsync(string message, double showDuration = 3);
/// <summary>
/// 显示提示信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
Task ShowInfoAsync(string message, double showDuration = 3);
}
2.接口实现
/// <summary>
/// 全局的冒泡消息服务类
/// </summary>
public class MessageBusServiceService:IMessageBusService
{
#region Private Members
private static BubbleWindow _bubbleWindow;
#endregion
#region Constructor
public MessageBusServiceService()
{
if (Application.Current.MainWindow != null)
Application.Current.MainWindow.Closing += (s, e) => _bubbleWindow.Close();
}
#endregion
#region Public Methods
/// <summary>
/// 显示错误/失败信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
public async Task ShowErrorAsync(string message, double showDuration = 3)
{
DefaultBubbleControl bubble = new DefaultBubbleControl
{
DataContext = new DefaultBubbleControlViewModel(
UIconNames.shibaitishi,
Color.FromRgb(255, 78, 49),
Color.FromRgb(163, 64, 64), message)
};
await ShowBubbleMessage(bubble,showDuration);
}
/// <summary>
/// 显示成功信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
public async Task ShowSuccessAsync(string message, double showDuration = 3)
{
DefaultBubbleControl bubble = new DefaultBubbleControl
{
DataContext = new DefaultBubbleControlViewModel(
UIconNames.chenggongtishi,
Color.FromRgb(0, 208, 117),
Color.FromRgb(46, 115, 85), message)
};
await ShowBubbleMessage(bubble,showDuration);
}
/// <summary>
/// 显示警告信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
public async Task ShowWarnAsync(string message, double showDuration = 3)
{
DefaultBubbleControl bubble = new DefaultBubbleControl
{
DataContext = new DefaultBubbleControlViewModel(
UIconNames.jinggaotishi,
Color.FromRgb(255, 168, 0),
Color.FromRgb(139, 113, 62), message)
};
await ShowBubbleMessage(bubble,showDuration);
}
/// <summary>
/// 显示提示信息
/// </summary>
/// <param name="message"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
public async Task ShowInfoAsync(string message, double showDuration = 3)
{
DefaultBubbleControl bubble = new DefaultBubbleControl
{
DataContext = new DefaultBubbleControlViewModel(
UIconNames.xinxitishi,
Color.FromRgb(0, 190, 255),
Color.FromRgb(48, 109, 130), message)
};
await ShowBubbleMessage(bubble,showDuration);
}
#endregion
#region Private Helpers
/// <summary>
/// 在打开气泡弹窗前初始化窗口
/// </summary>
private void BeforeOpenBubbleInitializeWindow()
{
if (_bubbleWindow != null)
{
_bubbleWindow.Close();
_bubbleWindow = null;
}
_bubbleWindow = new BubbleWindow();
_bubbleWindow.Show();
_bubbleWindow.Init();
}
/// <summary>
/// 开始定时指定秒数后消失
/// </summary>
/// <param name="bubble"></param>
/// <param name="showDuration"></param>
/// <returns></returns>
private async Task BeginRegularTimeDisposeAsync(UIElement bubble, double showDuration=1.5)
{
await Task.Delay(TimeSpan.FromSeconds(showDuration)).ContinueWith(x =>
{
_bubbleWindow.Dispatcher.BeginInvoke(new Action(() =>
{
_bubbleWindow.Close();
_bubbleWindow = null;
}));
});
}
/// <summary>
/// 显示气泡消息
/// </summary>
/// <param name="content"></param>
/// <param name="showDuration"></param>
private async Task ShowBubbleMessage(UIElement content,double showDuration=3)
{
BeforeOpenBubbleInitializeWindow();
_bubbleWindow.GrowlPanel.Children.Insert(0, content);
WindowHelper.SetWindowToForeground(_bubbleWindow);
await BeginRegularTimeDisposeAsync(content, showDuration);
}
#endregion
}
BubbleWindow
/// <summary>
/// 冒泡窗口类
/// </summary>
public class BubbleWindow : Window
{
/// <summary>
/// 内容面板
/// </summary>
public Panel GrowlPanel { get; set; }
public BubbleWindow()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
Background = new SolidColorBrush(Colors.Transparent);
ShowActivated = false;
ShowInTaskbar = false;
Topmost = true;
Focusable = false;
GrowlPanel = new StackPanel
{
VerticalAlignment = VerticalAlignment.Top
};
Content = new ScrollViewer
{
VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
HorizontalAlignment = HorizontalAlignment.Center,
Content = GrowlPanel
};
}
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
var desktopWorkingArea = SystemParameters.WorkArea;
Height = desktopWorkingArea.Height;
Width = desktopWorkingArea.Width;
Left = 0;
Top = 0;
}
protected override void OnSourceInitialized(EventArgs e)
=> InteropMethods.IntDestroyMenu(this.GetHwndSource().CreateHandleRef());
}
DefaultBubbleControl 是简单的气泡内容实现
<UserControl
x:Class="UOSS.Modules.Common.DefaultBubbleControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controlLibrary="clr-namespace:UOSS.ControlLibrary;assembly=UOSS.ControlLibrary" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:UOSS.Modules.Common" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Panel.ZIndex="100" FontSize="12" mc:Ignorable="d">
<Border
MinWidth="400" MinHeight="60" MaxWidth="700" Margin="5" Panel.ZIndex="1000"
CornerRadius="5">
<Border.Background>
<SolidColorBrush Opacity="0.8" Color="{Binding BubbleBackColor}" />
</Border.Background>
<Grid Margin="25,5,25,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Grid.Column="0" Width="24" Height="24" Margin="0,0,20,0" HorizontalAlignment="Left"
VerticalAlignment="Center" Background="White" CornerRadius="12">
<TextBlock
HorizontalAlignment="Center" VerticalAlignment="Center" Background="Transparent"
FontFamily="{controlLibrary:UIconFont}"
FontSize="24"
Text="{Binding FIconText}">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding IconBackColor}" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<TextBlock
Grid.Column="1" Margin="0,10,0,5" VerticalAlignment="Center" Foreground="White" LineHeight="20"
Text="{Binding Message}"
TextWrapping="Wrap" />
</Grid>
</Border>
</UserControl>
cs
/// <summary>
/// DefaultBubbleControl.xaml 的交互逻辑
/// </summary>
public partial class DefaultBubbleControl : UserControl
{
public DefaultBubbleControl()
{
InitializeComponent();
this.Loaded += DefaultBubbleControl_Loaded;
this.Unloaded += DefaultBubbleControl_Unloaded;
}
private async void DefaultBubbleControl_Unloaded(object sender, RoutedEventArgs e)
{
await this.SlideAndFadeOutToBottomAsync(0.3f);
}
private async void DefaultBubbleControl_Loaded(object sender, RoutedEventArgs e)
{
await this.SlideAndFadeInFromTopAsync(0.3f);
}
}