1.先上效果图:
2.1t提示框界面。 主窗口界面没什么内容,就放了一个触发按钮。先绘制通知窗口(一个关闭按钮,俩个文本控件),可以设置下ResizeMode="NoResize" WindowStyle="None" Topmost="True",
去掉窗口标题,并使提示窗口始终处于最上层。
<Border BorderThickness="1" BorderBrush="Black"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="6*" /> <RowDefinition /> </Grid.RowDefinitions> <Grid Background="White"> <Button Margin="5" HorizontalAlignment="Right" VerticalAlignment="Top" Background="White" BorderThickness="0" Click="Button_Click" Content=" × " FontSize="18" /> <TextBlock x:Name="tbTitle" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="16" Text="TextBlock" TextWrapping="Wrap" /> <TextBlock x:Name="tbContent" Margin="20,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="16" Text="TextBlock" TextWrapping="Wrap" /> </Grid> <Grid Grid.Row="2" Background="#F0F0F0" /> </Grid> </Border>
2.2主窗口后台代码。
NotifyData类是弹出窗口的推送消息。
List<Window1>计算高度时,如果窗口关闭,窗口就会从List中移除。
GetTopFrom负责计算弹出窗口距离屏幕顶端的高度。
Button_Click 传递消息,弹出窗口。
class NotifyData { public string Title { get; set; } public string Content { get; set; } }
public partial class MainWindow : Window { int i = 0; public static List<Window1> _dialogs = new List<Window1>(); public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { i++; NotifyData data = new NotifyData(); data.Title = "提示"; data.Content = "XXX余额不足,XXX余额不足,XXX余额不足,XXX余额不足" + i; Window1 dialog = new Window1();//new 一个通知 dialog.Closed += Dialog_Closed; dialog.TopFrom = GetTopFrom(); dialog.DataContext = data;//设置通知里要显示的数据 dialog.Show(); _dialogs.Add(dialog); } private void Dialog_Closed(object sender, EventArgs e) { var closedDialog = sender as Window1; _dialogs.Remove(closedDialog); } double GetTopFrom() { //屏幕的高度-底部TaskBar的高度。 double topFrom = System.Windows.SystemParameters.WorkArea.Bottom - 10; bool isContinueFind = _dialogs.Any(o => o.TopFrom == topFrom); while (isContinueFind) { topFrom = topFrom - 160;//此处100是NotifyWindow的高 160-100剩下的10 是通知之间的间距 isContinueFind = _dialogs.Any(o => o.TopFrom == topFrom); } if (topFrom <= 0) topFrom = System.Windows.SystemParameters.WorkArea.Bottom-10; return topFrom; } }
2.3消息提醒窗后台代码
NotificationWindow_Loaded 接收传过来的内容TopFrom和NotifyData,然后确定弹出窗口位置,并在5S后关闭窗口。
Button_Click 关闭窗口
public partial class Window1 : Window { public double TopFrom { get; set; } public Window1() { InitializeComponent(); this.Loaded += NotificationWindow_Loaded; } private void NotificationWindow_Loaded(object sender, RoutedEventArgs e) { NotifyData data = this.DataContext as NotifyData; if (data != null) { tbContent.Text = data.Content; tbTitle.Text = data.Title; } Window1 self = sender as Window1; if (self!=null) { double right=SystemParameters.WorkArea.Right-10;//工作区最右边的值 self.Top = TopFrom - 160; DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); animation.From = right; animation.To = right - self.ActualWidth; self.BeginAnimation(Window.LeftProperty, animation); Task.Factory.StartNew(delegate { int seconds = 5;//通知持续5s后消失 System.Threading.Thread.Sleep(TimeSpan.FromSeconds(seconds)); //Invoke到主进程中去执行 this.Dispatcher.Invoke(delegate { animation = new DoubleAnimation(); animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); animation.Completed += (s, a) => { self.Close(); };//动画执行完毕,关闭当前窗体 animation.From = right - self.ActualWidth; animation.To = right;//通知从左往右收回 self.BeginAnimation(Window.LeftProperty, animation); }); }); } } private void Button_Click(object sender, RoutedEventArgs e) { double right = SystemParameters.WorkArea.Right; DoubleAnimation animation = new DoubleAnimation(); animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); animation.Completed += (s, a) => { this.Close(); }; animation.From = right - this.ActualWidth; animation.To = right; this.BeginAnimation(Window.LeftProperty, animation); } }
3.源码下载地址
https://files-cdn.cnblogs.com/files/king10086/NoticeDemo.7z