首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# WinForm 表單淡入淡出效果實作 (Opacity 動畫)

     編輯:關於C#

利用 Form.Opacity (0.0 ~ 1.0) 搭配 Timer 定時器,即可實現視窗淡入 (載入時) 與淡出 (關閉時) 動畫。本文提供可直接繼承的基底類別 FadeForm,支援自訂速度、事件驅動關閉流程。

核心原理

  • Opacity:雙精度浮點數,0 完全透明,1 完全不透明。
  • Timer.Interval:建議 20~50ms (約 20~50 FPS)。
  • 每 Tick 遞增/遞減 Opacity 直到達標,然後停止 Timer 或呼叫 Close()。

可重用基底類別 FadeForm

using System;
using System.Windows.Forms;

public class FadeForm : Form
{
    private readonly Timer _timer = new() { Interval = 30 };
    private double _fadeInSpeed = 0.05;  // 每 Tick 增量
    private double _fadeOutSpeed = 0.05; // 每 Tick 減量
    private int _state; // 0=淡入, -1=淡出, 1=完成

    public double FadeInSpeed { get => _fadeInSpeed; set => _fadeInSpeed = Math.Clamp(value, 0.01, 0.5); }
    public double FadeOutSpeed { get => _fadeOutSpeed; set => _fadeOutSpeed = Math.Clamp(value, 0.01, 0.5); }

    protected FadeForm()
    {
        _timer.Tick += OnTimerTick;
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        Opacity = 0;
        _state = 0;
        _timer.Start();
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        switch (_state)
        {
            case 0: // 淡入
                Opacity += _fadeInSpeed;
                if (Opacity >= 1)
                {
                    Opacity = 1;
                    _state = 1;
                    _timer.Stop();
                }
                break;
            case -1: // 淡出
                Opacity -= _fadeOutSpeed;
                if (Opacity <= 0)
                {
                    Opacity = 0;
                    _timer.Stop();
                    base.Close(); // 真正關閉
                }
                break;
        }
    }

    /// 觸發淡出關閉流程
    public new void Close()
    {
        if (_state == 1) // 已完全顯示才允許淡出
        {
            _state = -1;
            _timer.Start();
        }
        else
        {
            base.Close(); // 尚未顯示完成直接關閉
        }
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        if (_state != -1 && e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true; // 取消預設關閉
            Close(); // 改用淡出關閉
        }
        base.OnFormClosing(e);
    }
}

使用範例

public class MyForm : FadeForm
{
    public MyForm()
    {
        FadeInSpeed = 0.08;  // 較快淡入
        FadeOutSpeed = 0.04; // 較慢淡出
        Text = "淡入淡出示範";
        Size = new Size(400, 300);
    }

    private void btnClose_Click(object sender, EventArgs e)
    {
        Close(); // 呼叫 FadeForm.Close() 觸發淡出
    }
}

進階改良建議

需求實作方向
非線性緩動 (Easing)引入 `double progress = 1 - Math.Pow(1 - t, 3)` (EaseOutCubic) 計算 Opacity
跨平台 (WPF/UWP/MAUI)使用 `DoubleAnimation` / `Storyboard` / `Animation` 系統原生動畫
效能:減少重繪設定 `this.DoubleBuffered = true`,避免閃爍
無障礙提供 `ReducedMotion` 設定關閉動畫 (檢查 `SystemParameters.MinimizeAnimation`)

常見問題

  • 關閉按鈕點兩次才關閉:確認 `OnFormClosing` 中 `e.Cancel = true` 並呼叫 `Close()` 觸發淡出,而非 `base.Close()`。
  • 淡出中再次點擊關閉:`_state == -1` 時直接 `base.Close()` 或忽略。
  • 顯示器縮放 (DPI) 導致 Opacity 異常:專案啟用 Per-Monitor DPI Aware。

結語

Opacity + Timer 是 WinForm 實現淡入淡出最簡單、相容性最好的方式。封裝為基底類別 `FadeForm` 後,所有視窗只需繼承並設定速度即可擁有一致的動畫體驗。現代專案若遷移至 WPF/WinUI/MAUI,請改用平台原生動畫系統以獲得 GPU 加速與豐富緩動函數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved