WPF 全局加载界面、多界面实现渐变过渡效果

news2025/6/4 17:38:49

WPF 全局加载界面与渐变过渡效果

完整实现方案

MainWindow.xaml

<Window x:Class="LoadingScreenDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:LoadingScreenDemo"
        mc:Ignorable="d"
        WindowStyle="None"
        AllowsTransparency="True"
        WindowState="Maximized"
        Background="Transparent"
        Loaded="Window_Loaded">
    
    <!-- 窗口阴影效果 -->
    <Border Margin="20" CornerRadius="10">
      
        <Grid>
            <!-- 黑色加载覆盖层(初始显示) -->
            <Grid x:Name="LoadingOverlay" 
                  Background="#FF0A0A0A"
                  Opacity="1"
                  Panel.ZIndex="100"
                  IsHitTestVisible="True">
                
                <!-- 加载动画 -->
                <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
                    <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                        <!-- 加载进度条 -->
                        <ProgressBar x:Name="LoadingProgress" 
                                     Width="400" 
                                     Height="20" 
                                     Margin="0,0,0,20"
                                     IsIndeterminate="True"
                                     Foreground="#FF4A90E2"
                                     Style="{StaticResource ModernProgressBar}"/>
                        
                        <!-- 加载文本 -->
                        <TextBlock Text="正在初始化应用程序..." 
                                   HorizontalAlignment="Center"
                                   Foreground="#CCFFFFFF"
                                   FontSize="18"
                                   FontWeight="SemiBold"/>
                        
                        <!-- 加载提示 -->
                        <TextBlock Text="请稍候,正在准备您的体验" 
                                   HorizontalAlignment="Center"
                                   Margin="0,10,0,0"
                                   Foreground="#99FFFFFF"
                                   FontSize="14"/>
                    </StackPanel>
                    
           
                </Grid>
            </Grid>
            
            <!-- 主内容区域(初始隐藏) -->
            <Grid x:Name="MainContent" Opacity="0" Panel.ZIndex="0">
                <!-- 背景图片 -->
                <Grid.Background>
                    <ImageBrush ImageSource="https://images.unsplash.com/photo-1519681393784-d120267933ba?ixlib=rb-4.0.3&auto=format&fit=crop&w=1920&q=80"
                                Stretch="UniformToFill" 
                                Opacity="0.9"/>
                </Grid.Background>
                
                <!-- 半透明覆盖层 -->
                <Rectangle Fill="#80111111"/>
                
                <!-- 主界面内容 -->
                <Grid Margin="30">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    
                    <!-- 主内容区 -->
                    <Border Grid.Row="1" Background="#20000000" Padding="20">

                    </Border>
                </Grid>
    </Border>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Media.Animation;
using System.Threading.Tasks;

namespace LoadingScreenDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
			this.Loaded += Window_Loaded;
        }

        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 模拟应用程序初始化过程
            await SimulateLoadingAsync();
            
            // 加载完成后显示主界面
            ShowMainContent();
        }

        private async Task SimulateLoadingAsync()
        {
            // 模拟加载进度
            for (int i = 0; i < 100; i++)
            {
                await Task.Delay(30); // 模拟耗时操作
                
                // 更新进度(实际应用中替换为真实进度)
                if (i % 10 == 0)
                {
                    // 更新加载提示文本
                    if (i < 30)
                        LoadingProgress.ToolTip = "正在初始化核心模块...";
                    else if (i < 60)
                        LoadingProgress.ToolTip = "正在加载用户数据...";
                    else if (i < 90)
                        LoadingProgress.ToolTip = "正在准备用户界面...";
                    else
                        LoadingProgress.ToolTip = "完成初始化...";
                }
            }
        }

        private void ShowMainContent()
        {
            // 创建动画
            var fadeInAnimation = new DoubleAnimation
            {
                From = 0,
                To = 1,
                Duration = TimeSpan.FromSeconds(1.5),
                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut }
            };

            var fadeOutAnimation = new DoubleAnimation
            {
                From = 1,
                To = 0,
                Duration = TimeSpan.FromSeconds(1),
                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut }
            };

            // 动画完成后移除加载层
            fadeOutAnimation.Completed += (s, args) => 
            {
                LoadingOverlay.Visibility = Visibility.Collapsed;
                LoadingOverlay.IsHitTestVisible = false; // 允许与主内容交互
            };

            // 启动动画
            MainContent.BeginAnimation(UIElement.OpacityProperty, fadeInAnimation);
            LoadingOverlay.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
        }

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = this.WindowState == WindowState.Maximized 
                ? WindowState.Normal 
                : WindowState.Maximized;
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
}

实现要点说明

1. 全局黑屏加载效果

  • 使用 LoadingOverlay 网格覆盖整个窗口
  • Panel.ZIndex="100" 确保加载层在最上方
  • IsHitTestVisible="True" 阻止用户与下层内容交互
  • 黑色背景 (#FF0A0A0A) 提供沉浸式加载体验

2. 加载进度指示器

  • 使用 ProgressBar 显示加载进度(设置为不确定模式)
  • 添加加载状态文本提示
  • 自定义进度条样式使其更现代化

3. 渐变显示主界面

  • 使用 DoubleAnimation 创建透明度渐变动画
  • 加载层淡出 (Opacity 1 → 0)
  • 主内容淡入 (Opacity 0 → 1)
  • 使用 CubicEase 缓动函数实现平滑过渡

4. 加载期间禁用交互

  • 设置 LoadingOverlay.IsHitTestVisible="True" 捕获所有输入事件
  • 动画完成后设置 IsHitTestVisible="False" 恢复交互

5. 主界面设计

  • 添加专业背景图片
  • 使用半透明覆盖层提升文字可读性
  • 实现自定义标题栏(最小化/最大化/关闭按钮)
  • 添加导航菜单和内容区域
  • 底部状态栏显示应用信息

6. 视觉效果增强

  • 窗口周围添加阴影效果
  • 所有元素使用圆角设计
  • 按钮添加悬停和点击效果
  • 使用半透明层创造深度感

实际应用建议

  1. 真实加载逻辑
private async Task RealLoadingAsync()
{
    // 1. 初始化核心模块
    await InitializeCoreModules();
    UpdateLoadingText("核心模块初始化完成...");
    
    // 2. 加载配置数据
    await LoadConfiguration();
    UpdateLoadingText("配置加载完成...");
    
    // 3. 连接数据库/服务
    await ConnectToServices();
    UpdateLoadingText("服务连接成功...");
    
    // 4. 准备用户界面
    await PrepareUserInterface();
    UpdateLoadingText("界面准备就绪...");
}

private void UpdateLoadingText(string message)
{
    Dispatcher.Invoke(() => {
        LoadingProgress.ToolTip = message;
    });
}
  1. 错误处理
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    try
    {
        await RealLoadingAsync();
        ShowMainContent();
    }
    catch (Exception ex)
    {
        // 显示错误信息
        ShowErrorDialog("初始化失败", ex.Message);
        
        // 退出应用
        Application.Current.Shutdown();
    }
}
  1. 性能优化
  • 使用异步加载避免UI冻结
  • 后台线程执行耗时操作
  • 分阶段加载资源

这个实现提供了专业的应用启动体验,确保在加载过程中用户无法与主界面交互,加载完成后通过平滑过渡显示主界面内容。您可以根据实际需求调整加载时间、动画效果和界面设计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2396409.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——优先级队列(PriorityQueue)

1.优先级队列 优先级队列可以看作队列的另一个版本&#xff0c;队列的返回元素是由是由插入顺序决定的&#xff0c;先进先出嘛&#xff0c;但是有时我们可能想要返回优先级较高的元素&#xff0c;比如最大值&#xff1f;这种场景下就由优先级队列登场。 优先级队列底层是由堆实…

代谢组数据分析(二十六):LC-MS/MS代谢组学和脂质组学数据的分析流程

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包依赖包安装包加载需要的R包数据下载以及转换mzML数据预处理代谢物注释LipidFinder过滤MultiABLER数据预处理过滤补缺失值对数变换数据标准化下游数据分析总结系统信息参考介…

【ARM】【FPGA】【硬件开发】Chapter.1 AXI4总线协议

Chapter.1 AXI4总线协议 作者&#xff1a;齐花Guyc(CAUC) 一、总线介绍 AXI4总线 AXI4总线就像是SoC内部的“高速公路”&#xff0c;负责在不同硬件模块之间高效传输数据。 AXI4协议通过 5个独立通道 传输数据和控制信号&#xff0c;每个通道都有自己的信号线&#xff0c;互…

把 jar 打包成 exe

1. 把自己的项目先正常打成jar包 2. 使用exe4j工具将jar转换为exe 2.1 exe4j下载地址&#xff1a;https://www.ej-technologies.com/download/exe4j/files 2.2 下载完成之后激活 2.3 可以点击Change License&#xff0c;输入秘钥L-g782dn2d-1f1yqxx1rv1sqd 2.4 直接下一步…

【目标检测】检测网络中neck的核心作用

1. neck最主要的作用就是特征融合&#xff0c;融合就是将具有不同大小感受野的特征图进行了耦合&#xff0c;从而增强了特征图的表达能力。 2. neck决定了head的数量&#xff0c;进而潜在决定了不同尺度样本如何分配到不同的head&#xff0c;这一点可以看做是将整个网络的多尺…

【经验】Ubuntu中设置terminator的滚动行数、从Virtualbox复制到Windows时每行后多一空行

1、设置terminator的滚动行数 1.1 问题描述 在终端 terminator 中&#xff0c;调试程序时&#xff0c;只能查看有限行数的打印日志&#xff0c;大约是500行&#xff0c;怎么能增加行数 1.2 解决方法 1&#xff09;安装terminator sudo apt install terminator和 terminato…

使用微软最近开源的WSL在Windows上优雅的运行Linux

install wsl https://github.com/microsoft/WSL/releases/download/2.4.13/wsl.2.4.13.0.x64.msi install any distribution from microsoft store, such as kali-linux from Kali office website list of distribution PS C:\Users\50240> wsl -l -o 以下是可安装的有…

HackMyVM-Teacher

信息搜集 主机发现 ┌──(kali㉿kali)-[~] └─$ nmap -sn 192.168.43.0/24 Starting Nmap 7.95 ( https://nmap.org ) at 2025-06-01 01:02 EDT Nmap scan report for 192.168.43.1 Host is up (0.0084s latency). MAC Address: C6:45:66:05:91:88 (Unknow…

BugKu Web渗透之矛盾

开启场景&#xff0c;打开网页。发现是一段php代码。 这段代码也很好理解&#xff0c;就是get方式传参num&#xff0c;如果num不是数字类型&#xff0c;那么输出num的值&#xff0c;并且num1时&#xff0c;输出flag的值。 首先看看is_numeric的意思。 开始我想到了使用科学技术…

Python实现P-PSO优化算法优化卷积神经网络CNN回归模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 随着人工智能和深度学习技术的快速发展&#xff0c;卷积神经网络&#xff08;CNN&#xff09;在图像分类、目标检测…

ssm 学习笔记day03

环境搭建 spring配置数据库 1.在pom.xml安装相应的依赖 2.在properties里面配置数据库的相关信息&#xff0c;需要强调的一点是&#xff0c;一定不要在properties里面添加任何空格&#xff0c;否则就会像我一样搞了两小时&#xff0c;数据一直报错&#xff0c;然后发现是空格的…

mkdir: cannot create directory ‘gitlab-stu’: No space left on device

Linux中创建目录时报错“mkdir: cannot create directory ‘gitlab-stu’: No space left on device”&#xff0c;磁盘空间不足。 使用df命令查看&#xff0c;发现 / 下面use%占满了&#xff1a; 查看inode使用情况&#xff1a; 可以看到docker的数据大部分存放在/var/lib/do…

ESP8285乐鑫SOCwifi芯片32bit MCU和2.4 GHz Wi-Fi

简介 ESP8285 拥有完整的且⾃成体系的 Wi-Fi ⽹络功能&#xff0c;既能够独⽴应⽤&#xff0c;也可以作为从机搭载于其他主机 MCU 运⾏。当 ESP8285 独⽴应⽤时&#xff0c;能够直接从外接 flash 中启动。内置的⾼速缓冲存储器有利于提⾼系统性能&#xff0c;并且优化存储系统。…

DL00916-基于深度学习的金枪鱼各类别目标检测含完整数据集

文末有获取方式 &#x1f680; 基于深度学习的金枪鱼目标检测——开创智能识别新领域&#xff01; 在计算机视觉和深度学习的快速发展中&#xff0c;目标检测 技术已成为提升行业效率的核心利器。而对于海洋生物领域&#xff0c;尤其是金枪鱼的 目标检测&#xff0c;更是填补了…

不可变集合类型转换异常

记录一个异常&#xff1a;class java.util.ImmutableCollections$ListN cannot be cast to class java.util.ArrayList (java.util.ImmutableCollections$ListN and java.util.ArrayList 文章目录 1、原因2、解决方式一3、解决方式二4、关于不可变集合的补充4.1 JDK8和9的对比4…

【PyQt5】从零开始的PyQt5 - QLabel篇

从零开始的PyQt5 - QLabel篇 引言一、简述二、例程2.1 显示到QWidget窗口上2.2 重新设置Label大小和对齐方式2.3 添加内容&#xff0c;设置边框2.4 显示富文本 三、参考 引言 QLabel主要用于显示文本或图像&#xff0c;不提供用户交互功能。本文主要简述PyQt5中的QLabel以及展…

多模态AI的企业应用场景:视觉+语言模型的商业价值挖掘

关键词&#xff1a;多模态AI | 视觉语言模型 | 企业应用 | 商业价值 | 人工智能 &#x1f4da; 文章目录 一、引言&#xff1a;多模态AI时代的到来二、多模态AI技术架构深度解析三、客服场景&#xff1a;智能化服务体验革命四、营销场景&#xff1a;精准投放与创意生成五、研…

数据结构(7)树-二叉树-堆

一、树 1.树的概述 现实生活中可以说处处有树。 在计算机里&#xff0c;有一种数据结构就是像现实中的树一样&#xff0c;有根&#xff0c;有分支&#xff0c;有叶子&#xff1b;一大片树就叫做森林。 这些性质抽象到计算机里也叫树&#xff0c;大致长这个样子&#xff1a; …

怎么快速判断一款MCU能否跑RTOS系统

最近有朋友在后台中私信我&#xff0c;说现在做项目的时候有时候总是会考虑要不要用RTOS&#xff0c;或者怎么考量什么时候该用RTOS比较好、 关于这个问题&#xff0c;我个人也是深有感触的&#xff0c;做开发这么久了&#xff0c;大大小小的产品都做过不少了。有用RTOS开发的…

使用原生前端技术封装一个组件

封装导航栏 navbar-template.html <header><nav><ul><li><a href"index.html"><i class"fas fa-home"></i> 主页</a></li><li><a href"#"><i class"fas fa-theate…