WPF 強大的繪圖與動畫系統,讓我們能輕易實作出極具視覺衝擊力的視窗轉場效果。本文示範如何利用 `OpacityMask` 搭配 `LinearGradientBrush` 與 `Storyboard` 動畫,打造漸變淡入(載入時)與淡出(關閉時)的登入視窗。
<Window x:Class="WpfFadeWindow.MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="登入系統" Height="350" Width="500"
WindowStyle="None" AllowsTransparency="True" Background="Transparent"
Loaded="Window_Loaded">
<Window.Resources>
<!-- 淡出動畫資源(關閉時使用) -->
<Storyboard x:Key="CloseStoryboard" x:Name="closeStoryboard">
<DoubleAnimation Storyboard.TargetName="LoginGrid"
Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[1].Offset"
From="1" To="0" Duration="0:0:2" />
<DoubleAnimation Storyboard.TargetName="LoginGrid"
Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[2].Offset"
From="1" To="0" Duration="0:0:1.5" BeginTime="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="LoginGrid"
Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[2].Color"
To="#00000000" Duration="0" />
</Storyboard>
<!-- 淡出用漸變畫筆(初始全不透明) -->
<LinearGradientBrush x:Key="CloseBrush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF000000" Offset="0" />
<GradientStop Color="#FF000000" Offset="1" />
<GradientStop Color="#FF000000" Offset="1" />
</LinearGradientBrush>
</Window.Resources>
<Grid x:Name="LoginGrid" Background="White">
<!-- 淡入用漸變遮罩(初始全透明) -->
<Grid.OpacityMask>
<LinearGradientBrush StartPoint="0.5,1" EndPoint="0.5,0">
<GradientStop Color="#00000000" Offset="0" />
<GradientStop Color="#00000000" Offset="1" />
<GradientStop Color="#00000000" Offset="1" />
</LinearGradientBrush>
</Grid.OpacityMask>
<!-- 淡入觸發器:視窗載入時自動播放 -->
<Grid.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<!-- 第 2 個 GradientStop:從 Offset=1 移至 0 -->
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[1].Offset"
From="1" To="0" Duration="0:0:1.5" />
<!-- 第 3 個 GradientStop:延遲 0.5s 開始 -->
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[2].Offset"
From="1" To="0" Duration="0:0:1" BeginTime="0:0:0.5" />
<!-- 第 3 個 GradientStop:顏色從透明變黑 -->
<ColorAnimation Storyboard.TargetProperty="OpacityMask.(GradientBrush.GradientStops)[2].Color"
To="#FF000000" Duration="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<!-- 登入表單內容 -->
<StackPanel VerticalAlignment="Center" Margin="40">
<TextBlock Text="系統登入" FontSize="24" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,20"/>
<TextBlock Text="帳號:" Margin="0,5"/>
<TextBox x:Name="txtAccount" Height="30" Margin="0,0,0,10"/>
<TextBlock Text="密碼:" Margin="0,5"/>
<PasswordBox x:Name="txtPassword" Height="30" Margin="0,0,0,20"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="btnLogin" Content="登入" Width="80" Height="30" Margin="0,0,10,0" Click="btnLogin_Click"/>
<Button x:Name="btnCancel" Content="取消" Width="80" Height="30" Click="btnCancel_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace WpfFadeWindow
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 淡入動畫完全由 XAML EventTrigger 處理,這裡可為空
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
// 驗證邏輯...
bool success = true; // 假設驗證通過
if (success)
{
// 開啟主視窗並關閉登入視窗
var main = new MainAppWindow();
main.Show();
this.Close(); // 直接關閉,無淡出效果(或依需求加淡出)
}
else
{
MessageBox.Show("帳號或密碼錯誤");
}
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
// 1. 禁用介面防止重複點擊
this.IsEnabled = false;
// 2. 套用淡出用畫筆(全不透明狀態開始淡出)
LoginGrid.OpacityMask = this.Resources["CloseBrush"] as LinearGradientBrush;
// 3. 取得並啟動淡出動畫
var storyboard = this.Resources["CloseStoryboard"] as Storyboard;
// 4. 動畫完成後真正關閉視窗
storyboard.Completed += (s, args) => this.Close();
storyboard.Begin();
}
}
}
<LinearGradientBrush>
<GradientStop x:Name="stop0" Color="#00000000" Offset="0" /> <!-- 索引 0:起始端 -->
<GradientStop x:Name="stop1" Color="#00000000" Offset="1" /> <!-- 索引 1:中間控制點 -->
<GradientStop x:Name="stop2" Color="#00000000" Offset="1" /> <!-- 索引 2:結束端 -->
</LinearGradientBrush>
動畫針對 `stop1` 與 `stop2` 的 `Offset` 從 1→0 移動,配合 `stop2` 的 `Color` 從透明→黑,產生「由下往上」或「由上往下」的漸變揭露效果。
視窗必須設定:
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent"
否則 `OpacityMask` 只會在視窗客戶區內生效,無法實現整個視窗的漸變。

WPF 的 `OpacityMask` + `GradientBrush` + `Storyboard` 組合,提供了極具彈性的視窗轉場實作方式。完全宣告式的 XAML 淡入動畫與程式碼觸發的淡出動畫相輔相成,無需第三方函式庫即可打造專業級的使用者體驗。