I am using .NET and am creating a desktop app/service that will display notifications in the corner of my Desktop when certain events are triggered. I don't want to use a regular Message Box b/c that would be too intrusive. I want notifications to slide into view and then fade out after a few seconds. I am thinking of something that will act very much like the Outlook alerts that one gets when a new message arrives. The question is: Should I use WPF for this? I've never done anything with WPF but will happily try it if that's best means to the end. Is there a way to accomplish this with regular .NET libraries?
+2
A:
WPF makes this absolutely trivial: It would proably take ten minutes or less. Here are the steps:
- Create a Window, set AllowsTransparency="true" and add a Grid to it
- Set the Grid's RenderTransform to a ScaleTransform with origin of 0,1
- Create an animation on the grid that animates the ScaleX 0 to 1 then later animates the Opacity from 1 to 0
- In the constructor calculate Window.Top and Window.Left to place the window in the lower right-hand corner of the screen.
That's all there is to it.
Using Expression Blend it took about 8 minutes me to generate the following working code:
<Window
x:Class="NotificationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Notification Popup" Width="300" SizeToContent="Height"
WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Grid RenderTransformOrigin="0,1" >
<!-- Notification area -->
<Border BorderThickness="1" Background="Beige" BorderBrush="Black" CornerRadius="10">
<StackPanel Margin="20">
<TextBlock TextWrapping="Wrap" Margin="5">
<Bold>Notification data</Bold><LineBreak /><LineBreak />
Something just happened and you are being notified of it.
</TextBlock>
<CheckBox Content="Checkable" Margin="5 5 0 5" />
<Button Content="Clickable" HorizontalAlignment="Center" />
</StackPanel>
</Border>
<!-- Animation -->
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.RenderTransform>
<ScaleTransform ScaleY="1" />
</Grid.RenderTransform>
</Grid>
</Window>
With code behind:
using System;
using System.Windows;
using System.Windows.Threading;
public partial class NotificationWindow
{
public NotificationWindow()
{
InitializeComponent();
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() =>
{
var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom));
this.Left = corner.X - this.ActualWidth - 100;
this.Top = corner.Y - this.ActualHeight;
}));
}
}
Since WPF is one of the regular .NET libraries, the answer is yes, it is possible to accomplish this with the "regular .NET libraries".
If you're asking if there is a way to do this without using WPF the answer is still yes, but it is extremely complex and will take more like 5 days than 5 minutes.
Ray Burns
2010-06-14 08:03:36
This is great. Works like a charm. Thank you! Impressive how little code it took.
Antony Highsky
2010-06-14 14:48:03
+ Cool, you've just save me some time as well! Thanks)
Koistya Navin
2010-09-02 11:00:54