Notification.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System;
  2. using System.ComponentModel;
  3. using System.Windows;
  4. using System.Windows.Threading;
  5. using HandyControl.Data;
  6. using HandyControl.Tools;
  7. namespace HandyControl.Controls;
  8. public sealed class Notification : System.Windows.Window
  9. {
  10. private const int WaitTime = 6;
  11. /// <summary>
  12. /// 计数
  13. /// </summary>
  14. private int _tickCount;
  15. /// <summary>
  16. /// 关闭计时器
  17. /// </summary>
  18. private DispatcherTimer _timerClose;
  19. private ShowAnimation ShowAnimation { get; set; }
  20. private bool _shouldBeClosed;
  21. public Notification()
  22. {
  23. WindowStyle = WindowStyle.None;
  24. AllowsTransparency = true;
  25. }
  26. public static Notification Show(object content, ShowAnimation showAnimation = ShowAnimation.None, bool staysOpen = false)
  27. {
  28. var notification = new Notification
  29. {
  30. Content = content,
  31. Opacity = 0,
  32. ShowAnimation = showAnimation
  33. };
  34. notification.Show();
  35. var desktopWorkingArea = SystemParameters.WorkArea;
  36. var leftMax = desktopWorkingArea.Width - notification.ActualWidth;
  37. var topMax = desktopWorkingArea.Height - notification.ActualHeight;
  38. switch (showAnimation)
  39. {
  40. case ShowAnimation.None:
  41. notification.Opacity = 1;
  42. notification.Left = leftMax;
  43. notification.Top = topMax;
  44. break;
  45. case ShowAnimation.HorizontalMove:
  46. notification.Opacity = 1;
  47. notification.Left = desktopWorkingArea.Width;
  48. notification.Top = topMax;
  49. notification.BeginAnimation(LeftProperty, AnimationHelper.CreateAnimation(leftMax));
  50. break;
  51. case ShowAnimation.VerticalMove:
  52. notification.Opacity = 1;
  53. notification.Left = leftMax;
  54. notification.Top = desktopWorkingArea.Height;
  55. notification.BeginAnimation(TopProperty, AnimationHelper.CreateAnimation(topMax));
  56. break;
  57. case ShowAnimation.Fade:
  58. notification.Left = leftMax;
  59. notification.Top = topMax;
  60. notification.BeginAnimation(OpacityProperty, AnimationHelper.CreateAnimation(1));
  61. break;
  62. default:
  63. notification.Opacity = 1;
  64. notification.Left = leftMax;
  65. notification.Top = topMax;
  66. break;
  67. }
  68. if (!staysOpen) notification.StartTimer();
  69. return notification;
  70. }
  71. protected override void OnClosing(CancelEventArgs e)
  72. {
  73. base.OnClosing(e);
  74. if (_shouldBeClosed)
  75. {
  76. return;
  77. }
  78. var desktopWorkingArea = SystemParameters.WorkArea;
  79. switch (ShowAnimation)
  80. {
  81. case ShowAnimation.None:
  82. break;
  83. case ShowAnimation.HorizontalMove:
  84. {
  85. var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Width);
  86. animation.Completed += Animation_Completed;
  87. BeginAnimation(LeftProperty, animation);
  88. e.Cancel = true;
  89. _shouldBeClosed = true;
  90. }
  91. break;
  92. case ShowAnimation.VerticalMove:
  93. {
  94. var animation = AnimationHelper.CreateAnimation(desktopWorkingArea.Height);
  95. animation.Completed += Animation_Completed;
  96. BeginAnimation(TopProperty, animation);
  97. e.Cancel = true;
  98. _shouldBeClosed = true;
  99. }
  100. break;
  101. case ShowAnimation.Fade:
  102. {
  103. var animation = AnimationHelper.CreateAnimation(0);
  104. animation.Completed += Animation_Completed;
  105. BeginAnimation(OpacityProperty, animation);
  106. e.Cancel = true;
  107. _shouldBeClosed = true;
  108. }
  109. break;
  110. }
  111. }
  112. private void Animation_Completed(object sender, EventArgs e) => Close();
  113. /// <summary>
  114. /// 开始计时器
  115. /// </summary>
  116. private void StartTimer()
  117. {
  118. _timerClose = new DispatcherTimer
  119. {
  120. Interval = TimeSpan.FromSeconds(1)
  121. };
  122. _timerClose.Tick += delegate
  123. {
  124. if (IsMouseOver)
  125. {
  126. _tickCount = 0;
  127. return;
  128. }
  129. _tickCount++;
  130. if (_tickCount >= WaitTime) Close();
  131. };
  132. _timerClose.Start();
  133. }
  134. }