Steps:
1.) Create a WPF Project in Visual Studio. I named mine FadingPopup. (Note: You can use 3.5 or 4.0, but you will need to use 4.0 if you want to take advantage of the animation EasingFunctions.)
2.) Add a User Control with the following code:
FadingPopupControl.xaml
<UserControl x:Class="FadingPopup.FadingPopupControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" BorderThickness="0" Margin="0">
<UserControl.Resources>
<Storyboard x:Name="StatusFader" x:Key="StatusFader" Completed="StatusFader_Completed">
<DoubleAnimation Storyboard.TargetName="popupBackground" Storyboard.TargetProperty="Opacity" From="0.7" To="0" BeginTime="0:0:0" Duration="0:0:1.5">
<DoubleAnimation.EasingFunction>
<ExponentialEase Exponent="10" EasingMode="EaseIn" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</UserControl.Resources>
<Popup Name="popup" Placement="Center" PopupAnimation="Fade" AllowsTransparency="True">
<Grid Background="Transparent">
<Grid Name="popupBackground" Background="Black" Grid.Column="0" Grid.Row="0" />
<Label Name="popupLabel" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Foreground="White" VerticalAlignment="Center" Background="Transparent" Grid.Column="0" Grid.Row="0"/>
</Grid>
</Popup>
</UserControl>
FadingPopupControl.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace FadingPopup
{
public partial class FadingPopupControl : UserControl
{
Window ParentWindow { get; set; }
public FadingPopupControl()
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
}
public void ShowDialogBox(Window parentWindow, string message)
{
ParentWindow = parentWindow;
popupLabel.Content = message;
Storyboard StatusFader = (Storyboard)Resources["StatusFader"];
ParentWindow.IsEnabled = false;
FrameworkElement root = (FrameworkElement)ParentWindow.Content;
this.Height = root.ActualHeight;
this.Width = root.ActualWidth;
//TODO: Determine why there is 1 pixel extra whitespace.
//Tried playing with Margins and Alignment to no avail.
popup.Height = root.ActualHeight + 1;
popup.Width = root.ActualWidth + 1;
popup.IsOpen = true;
StatusFader.Begin(popupBackground);
}
void StatusFader_Completed(object sender, EventArgs e)
{
popup.IsOpen = false;
ParentWindow.IsEnabled = true;
}
}
}
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace FadingPopup
{
public partial class FadingPopupControl : UserControl
{
Window ParentWindow { get; set; }
public FadingPopupControl()
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
}
public void ShowDialogBox(Window parentWindow, string message)
{
ParentWindow = parentWindow;
popupLabel.Content = message;
Storyboard StatusFader = (Storyboard)Resources["StatusFader"];
ParentWindow.IsEnabled = false;
FrameworkElement root = (FrameworkElement)ParentWindow.Content;
this.Height = root.ActualHeight;
this.Width = root.ActualWidth;
//TODO: Determine why there is 1 pixel extra whitespace.
//Tried playing with Margins and Alignment to no avail.
popup.Height = root.ActualHeight + 1;
popup.Width = root.ActualWidth + 1;
popup.IsOpen = true;
StatusFader.Begin(popupBackground);
}
void StatusFader_Completed(object sender, EventArgs e)
{
popup.IsOpen = false;
ParentWindow.IsEnabled = true;
}
}
}
3.) In the MainWindow.xaml, add a Button with a PreviewMouseLeftButtonDown event handler.
4.) Add a local reference and then your popup control.
5.) In your button event handler, initiate the popup.
MainWindow.xaml
<Window x:Class="FadingPopup.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FadingPopup"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="Test1" Height="40" Width="80" Content="Test1" Grid.Column="0" AllowDrop="False" PreviewMouseLeftButtonDown="Test1_PreviewMouseLeftButtonDown" />
<local:FadingPopupControl x:Name="popup" />
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Input;
namespace FadingPopup
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Test1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
popup.ShowDialogBox(Test1, "The is a sample message...");
}
}
}
Screenshots
This fades out in 1.2 seconds
I maybe detected an error. As I recreated your example, which is very useful, it throwed an error in the line "popup.showdialog..." I'm not used to code with C# but as far as I understand the code the first parameter of showdialog should be a window and not the button "test1". So I replaced that with:
ReplyDeletepopup.showdialog(this, "The message...");
and it worked (?=
Anonymous...
ReplyDeletetry getting the parent window that the control want...
see http://viblend.wordpress.com/2011/03/10/find-the-parent-window-of-a-wpf-control/
and then change:
popup.ShowDialogBox(Test1, "The is a sample message...")
to
popup.ShowDialogBox(GetParentWindow(Test1), "The is a sample message...")
Thanks Claude. Sadly, I have neglected comments as of late.
ReplyDeleteSet the name in MainWindow.xaml (x:Name="window1") and call the dialog as
ReplyDeletepopup.ShowDialogBox(window1, "The is a sample message...");
BR,
Great control you have here. I've been looking for something like this. Onyl it should open when I click a button and it should only close again when I click a button on the popup.
ReplyDeleteIs this doable? Can I modify your contorl to make it work like this? I've been struggling with this for sometime now :(
Thx for any help or pointers..
Stieven
it was exactly what i needed. Thanks a lot
ReplyDelete