I have been trying to create a notification window, but I’m struggling to figure out why this opacity shift is not happening when I run it. Instead the window will hold for a second then close without any visible changes. All my other attempts via other methods have failed too, so it must be some property I am missing. Thanks for any help!
public void RunForm(string error, MessageBoxIcon icon, int duration)
{
lblMessage.Text = error;
Icon i = ToSystemIcon(icon);
if (i != null)
{
BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(i.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
imgIcon.Source = bs;
}
this.WindowStartupLocation = WindowStartupLocation.Manual;
this.Show();
this.Left = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Right - this.RestoreBounds.Width - 20;
this.Top = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Bottom - this.RestoreBounds.Height - 20;
while (this.Opacity > 0)
{
this.Opacity -= 0.05;
Thread.Sleep(50);
}
this.Close();
}
<Window Width="225" Height="140" VerticalContentAlignment="Center" HorizontalAlignment="Center" ShowActivated="True" ShowInTaskbar="False"
ResizeMode="NoResize" Grid.IsSharedSizeScope="False" SizeToContent="Height" WindowStyle="None" BorderBrush="Gray"
BorderThickness="1.5" Background="White" Topmost="True" AllowsTransparency="True" Opacity="1">
<Grid Height="Auto" Name="grdNotificationBox" >
<Image Margin="12,12,0,0" Name="imgIcon" Stretch="Fill" HorizontalAlignment="Left" Width="32" Height="29" VerticalAlignment="Top" />
<TextBlock Name="lblMessage" TextWrapping="Wrap" Margin="57,11,17,11"></TextBlock>
</Grid>
This can’t work:
The complete WPF handling is done in one single thread (technically two but not important). you change the opacity and directly let the ui thread sleep, change it again and send it back to sleep. The ui thread never got any time to process what you did. Even removing the sleep would not help, because than it would be much to fast, and the ui thread could not handle any requests aswell. Its important to understand that your code and WPFs handling is done in the same thread, the longer you need, the less time WPF got and vice versa.
To solve it you need to use animations. They are exactly for these kind of thing. Checkout this thread.