我继续为此创建了一个CodePlex网站,其中包括“ Toast Popups”和控件“ Help Balloons”。这些版本的功能比下面描述的功能更多。 https://toastspopuphelpballoon.codeplex.com。
对于我正在寻找的解决方案来说,这是一个很好的起点。我做了一些修改以满足我的要求:
- 我想在鼠标悬停时停止动画。
- 鼠标离开时“重置”动画。
- 当不透明度达到0时,关闭窗口。
- 堆叠Toast(如果窗口数超过屏幕高度,则无法解决问题)
- 从我的ViewModel调用Load
这是我的XAML
<Window x:Class="Foundation.FundRaising.DataRequest.Windows.NotificationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="NotificationWindow" Height="70" Width="300" ShowInTaskbar="False"
WindowStyle="None" AllowsTransparency="True"
Background="Transparent">
<Grid RenderTransformOrigin="0,1" >
<Border BorderThickness="2" Background="{StaticResource GradientBackground}" BorderBrush="DarkGray" CornerRadius="7">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Column="0"
Grid.RowSpan="2"
Source="Resources/data_information.png"
Width="40" Height="40"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<Image Grid.Column="2"
Source="Resources/error20.png"
Width="20"
Height="20"
VerticalAlignment="Center"
ToolTip="Close"
HorizontalAlignment="Center"
Cursor="Hand" MouseUp="ImageMouseUp"/>
<TextBlock Grid.Column="1"
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontWeight="Bold" FontSize="15"
Text="A Request has been Added"/>
<Button Grid.Column="1"
Grid.Row="1"
FontSize="15"
Margin="0,-3,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Click Here to View"
Style="{StaticResource LinkButton}"/>
</Grid>
</Border>
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="StoryboardLoad">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="0.0" To="1.0" Duration="0:0:2" />
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:8" BeginTime="0:0:5" Completed="DoubleAnimationCompleted"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<RemoveStoryboard BeginStoryboardName="StoryboardLoad"/>
<RemoveStoryboard BeginStoryboardName="StoryboardFade"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard x:Name="StoryboardFade">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:8" BeginTime="0:0:2" Completed="DoubleAnimationCompleted"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.RenderTransform>
<ScaleTransform ScaleY="1" />
</Grid.RenderTransform>
</Grid>
背后的代码
public partial class NotificationWindow : Window
{
public NotificationWindow()
: base()
{
this.InitializeComponent();
this.Closed += this.NotificationWindowClosed;
}
public new void Show()
{
this.Topmost = true;
base.Show();
this.Owner = System.Windows.Application.Current.MainWindow;
this.Closed += this.NotificationWindowClosed;
var workingArea = Screen.PrimaryScreen.WorkingArea;
this.Left = workingArea.Right - this.ActualWidth;
double top = workingArea.Bottom - this.ActualHeight;
foreach (Window window in System.Windows.Application.Current.Windows)
{
string windowName = window.GetType().Name;
if (windowName.Equals("NotificationWindow") && window != this)
{
window.Topmost = true;
top = window.Top - window.ActualHeight;
}
}
this.Top = top;
}
private void ImageMouseUp(object sender,
System.Windows.Input.MouseButtonEventArgs e)
{
this.Close();
}
private void DoubleAnimationCompleted(object sender, EventArgs e)
{
if (!this.IsMouseOver)
{
this.Close();
}
}
}
来自ViewModel的调用:
private void ShowNotificationExecute()
{
App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
() =>
{
var notify = new NotificationWindow();
notify.Show();
}));
}
XAML中引用的样式:
<Style x:Key="LinkButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock>
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Cursor" Value="Hand"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextDecorations="Underline" Text="{TemplateBinding Content}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<LinearGradientBrush x:Key="GradientBackground" EndPoint="0.504,1.5" StartPoint="0.504,0.03">
<GradientStop Color="#FFFDD5A7" Offset="0"/>
<GradientStop Color="#FFFCE79F" Offset="0.567"/>
</LinearGradientBrush>
更新:关闭窗体时,我添加了此事件处理程序以“删除”其他窗口。
private void NotificationWindowClosed(object sender, EventArgs e)
{
foreach (Window window in System.Windows.Application.Current.Windows)
{
string windowName = window.GetType().Name;
if (windowName.Equals("NotificationWindow") && window != this)
{
if (window.Top < this.Top)
{
window.Top = window.Top + this.ActualHeight;
}
}
}
}