在 WPF 启动界面中心加载 GIF 动图

在 WPF 启动界面中心加载 GIF 动图

在 WPF 启动界面中心加载 GIF 动图可以通过多种方式实现。下面我将提供一个完整的解决方案,包括使用第三方库和纯 WPF 实现两种方法。

方法一:使用 WpfAnimatedGif 库(推荐)

这是最简单可靠的方法,使用专门处理 GIF 动画的库。

实现步骤:

  1. 安装 NuGet 包

    powershell 复制代码
    Install-Package WpfAnimatedGif
  2. 创建启动窗口 (SplashScreen.xaml)

xml 复制代码
<Window x:Class="YourNamespace.SplashScreen"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:gif="http://wpfanimatedgif.codeplex.com"
        WindowStyle="None" 
        AllowsTransparency="True"
        Background="Transparent"
        WindowStartupLocation="CenterScreen"
        Width="400" Height="400">
    
    <Grid>
        <!-- 背景 -->
        <Border CornerRadius="20" Background="#1E1E1E" Opacity="0.9"
                BorderBrush="#3F3F46" BorderThickness="1">
            <!-- 阴影效果 -->
            <Border.Effect>
                <DropShadowEffect BlurRadius="20" ShadowDepth="0" 
                                  Color="#000000" Opacity="0.5"/>
            </Border.Effect>
        </Border>
        
        <!-- 中心 GIF 动画 -->
        <Image x:Name="LoadingGif" 
               gif:ImageBehavior.AnimatedSource="/Assets/loading.gif"
               gif:ImageBehavior.AutoStart="True"
               Width="200" Height="200"
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
        
        <!-- 状态文本 -->
        <TextBlock x:Name="StatusText" Text="正在加载..." 
                   Foreground="#E0E0E0" FontSize="16"
                   HorizontalAlignment="Center" VerticalAlignment="Bottom"
                   Margin="0,0,0,30"/>
    </Grid>
</Window>
  1. 在代码中更新状态文本 (SplashScreen.xaml.cs)
csharp 复制代码
using System.Windows;

namespace YourNamespace
{
    public partial class SplashScreen : Window
    {
        public SplashScreen()
        {
            InitializeComponent();
        }
        
        // 更新状态文本的方法
        public void UpdateStatus(string message)
        {
            StatusText.Text = message;
        }
    }
}
  1. 在 App.xaml.cs 中使用启动窗口
csharp 复制代码
using System;
using System.Threading.Tasks;
using System.Windows;

namespace YourNamespace
{
    public partial class App : Application
    {
        private SplashScreen _splashScreen;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            
            // 创建并显示启动窗口
            _splashScreen = new SplashScreen();
            _splashScreen.Show();
            
            // 异步初始化应用
            Task.Run(() => InitializeApplication())
                .ContinueWith(t => 
                {
                    // 初始化完成后切换到主界面
                    Dispatcher.Invoke(() => SwitchToMainWindow());
                }, TaskScheduler.FromCurrentSynchronizationContext());
        }

        private void InitializeApplication()
        {
            // 更新状态信息
            UpdateSplashStatus("正在加载配置...");
            Task.Delay(800).Wait();
            
            UpdateSplashStatus("正在初始化数据库...");
            Task.Delay(1200).Wait();
            
            UpdateSplashStatus("正在准备界面...");
            Task.Delay(600).Wait();
        }

        private void UpdateSplashStatus(string message)
        {
            Dispatcher.Invoke(() => 
            {
                if (_splashScreen != null)
                {
                    _splashScreen.UpdateStatus(message);
                }
            });
        }

        private void SwitchToMainWindow()
        {
            // 创建主窗口
            var mainWindow = new MainWindow();
            
            // 关闭启动窗口
            _splashScreen.Close();
            _splashScreen = null;
            
            // 显示主窗口
            mainWindow.Show();
        }
    }
}
  1. 修改 App.xaml
xml 复制代码
<Application x:Class="YourNamespace.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="Application_Startup"
             ShutdownMode="OnExplicitShutdown">
</Application>

优化建议

1. 添加淡入淡出效果

在切换窗口时添加平滑的动画效果:

csharp 复制代码
private void SwitchToMainWindow()
{
    // 创建主窗口但不立即显示
    var mainWindow = new MainWindow();
    mainWindow.Opacity = 0;
    
    // 启动窗口淡出
    var fadeOut = new DoubleAnimation(0, TimeSpan.FromSeconds(0.5));
    fadeOut.Completed += (s, e) => 
    {
        _splashScreen.Close();
        _splashScreen = null;
        
        // 主窗口淡入
        mainWindow.Show();
        var fadeIn = new DoubleAnimation(1, TimeSpan.FromSeconds(0.5));
        mainWindow.BeginAnimation(Window.OpacityProperty, fadeIn);
    };
    
    _splashScreen.BeginAnimation(Window.OpacityProperty, fadeOut);
}

2. 处理 GIF 资源加载问题

确保 GIF 文件设置为资源:

  1. 在项目资源管理器中右键点击 GIF 文件
  2. 选择"属性"
  3. 设置"生成操作"为"Resource"

3. 添加加载进度指示器

xml 复制代码
<Grid>
    <!-- ... 其他元素 ... -->
    
    <!-- 圆形进度条 -->
    <ProgressBar x:Name="LoadingProgress" 
                 Value="0" Minimum="0" Maximum="100"
                 Height="6" Width="300"
                 HorizontalAlignment="Center" VerticalAlignment="Bottom"
                 Margin="0,0,0,60"
                 Foreground="#0EA5E9">
        <ProgressBar.Template>
            <ControlTemplate TargetType="ProgressBar">
                <Grid>
                    <Border CornerRadius="3" Background="#3F3F46" 
                            BorderThickness="0" Height="6"/>
                    <Border CornerRadius="3" Background="#0EA5E9" 
                            BorderThickness="0" Height="6"
                            HorizontalAlignment="Left"
                            Width="{TemplateBinding Value}"/>
                </Grid>
            </ControlTemplate>
        </ProgressBar.Template>
    </ProgressBar>
</Grid>

在代码中更新进度:

csharp 复制代码
// 在 SplashScreen 中添加
public void UpdateProgress(int value)
{
    LoadingProgress.Value = value;
}

// 在 App.xaml.cs 中
private void InitializeApplication()
{
    UpdateProgress(10);
    UpdateSplashStatus("正在加载配置...");
    Task.Delay(800).Wait();
    
    UpdateProgress(40);
    UpdateSplashStatus("正在初始化数据库...");
    Task.Delay(1200).Wait();
    
    UpdateProgress(80);
    UpdateSplashStatus("正在准备界面...");
    Task.Delay(600).Wait();
    
    UpdateProgress(100);
}

private void UpdateProgress(int value)
{
    Dispatcher.Invoke(() => 
    {
        if (_splashScreen != null)
        {
            _splashScreen.UpdateProgress(value);
        }
    });
}

常见问题解决方案

1. GIF 不显示或不动

  • 确保 GIF 文件路径正确
  • 检查 GIF 文件属性设置为"Resource"
  • 尝试使用完整资源路径:pack://application:,,,/YourAppName;component/Assets/loading.gif
  • 确保 GIF 不是单帧图像

2. 启动界面位置不居中

  • 设置 WindowStartupLocation="CenterScreen"
  • 确保启动窗口没有设置 LeftTop 属性

3. 背景不透明

  • 确保 AllowsTransparency="True"
  • 设置 Background="Transparent"
  • 移除窗口边框:WindowStyle="None"

4. 内存泄漏

  • 在关闭窗口时停止动画:

    csharp 复制代码
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        
        // 停止 GIF 动画
        if (gifBehavior != null)
        {
            ImageBehavior.SetAnimatedSource(LoadingGif, null);
        }
        
        // 清除资源
        LoadingGif.Source = null;
        LoadingGif = null;
    }

5. 多显示器支持

csharp 复制代码
public SplashScreen()
{
    InitializeComponent();
    
    // 在屏幕中心显示
    var screen = System.Windows.Forms.Screen.PrimaryScreen;
    var screenWidth = screen.Bounds.Width;
    var screenHeight = screen.Bounds.Height;
    
    Left = (screenWidth - Width) / 2;
    Top = (screenHeight - Height) / 2;
}

总结

在 WPF 启动界面中心加载 GIF 动画可以通过以下步骤实现:

  1. 使用 WpfAnimatedGif 库(推荐)或创建自定义 GIF 控件
  2. 设计透明无边框的启动窗口
  3. 将 GIF 放置在窗口中心
  4. 添加状态文本和进度指示器
  5. 在 App 类中管理启动窗口的生命周期
  6. 添加动画效果提升用户体验

对于大多数项目,推荐使用 WpfAnimatedGif 库,因为它简单可靠且支持完整的 GIF 功能。如果你有特殊需求或不想添加外部依赖,可以使用自定义控件方法。

无论选择哪种方法,都要注意资源管理和内存释放,确保启动窗口关闭后不会留下任何资源占用。

相关推荐
FuckPatience2 天前
WPF 具有跨线程功能的UI元素
wpf
诗仙&李白2 天前
HEFrame.WpfUI :一个现代化的 开源 WPF UI库
ui·开源·wpf
He BianGu2 天前
【笔记】在WPF中Binding里的详细功能介绍
笔记·wpf
He BianGu2 天前
【笔记】在WPF中 BulletDecorator 的功能、使用方式并对比 HeaderedContentControl 与常见 Panel 布局的区别
笔记·wpf
123梦野3 天前
WPF——效果和可视化对象
wpf
He BianGu3 天前
【笔记】在WPF中Decorator是什么以及何时优先考虑 Decorator 派生类
笔记·wpf
时光追逐者4 天前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf
He BianGu4 天前
【笔记】介绍 WPF XAML 中 Binding 的 StringFormat详细功能
笔记·wpf
Rotion_深5 天前
C# WPF使用线程池运行Action方法
c#·wpf·线程池
攻城狮CSU5 天前
WPF 深入系列.2.布局系统.尺寸属性
wpf