You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MAUI所有内容页面添加可全局控制显隐的ProgressBar

实现全局可显隐的ProgressBar Frame

1. 创建全局加载状态ViewModel

创建单例ViewModel统一管理加载状态,确保所有页面共享同一状态实例:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Mobile
{
    public class LoadingViewModel : INotifyPropertyChanged
    {
        private bool _isVisible;
        private string _loadingText = "加载中...";

        public bool IsVisible
        {
            get => _isVisible;
            set
            {
                _isVisible = value;
                OnPropertyChanged();
            }
        }

        public string LoadingText
        {
            get => _loadingText;
            set
            {
                _loadingText = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        // 单例实例
        public static LoadingViewModel Instance { get; } = new LoadingViewModel();
    }
}

2. 修改AppShell布局,添加全局加载Frame

将原有Shell内容包裹在Grid中,新增覆盖全屏的加载Frame,绑定ViewModel属性实现自动显隐:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Mobile.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Mobile"
    Shell.FlyoutBehavior="Flyout"
    Title="FactorPro"
    Shell.NavBarIsVisible="True"
    Shell.TabBarIsVisible="False"
    Shell.FlyoutItemIsVisible="False">

    <!-- 用Grid同时承载原有Shell内容和加载Frame -->
    <Grid>
        <!-- 原有Shell核心内容 -->
        <Grid>
            <Shell.ItemTemplate>
                <DataTemplate>
                    <Grid Style="{StaticResource FloutItemStyle}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="80" />
                            <ColumnDefinition Width="150" />
                        </Grid.ColumnDefinitions>
                        <Image Source="{Binding FlyoutIcon}"
                               Margin="10"
                               HeightRequest="50"
                               HorizontalOptions="EndAndExpand" />
                        <Label Grid.Column="1"
                               Text="{Binding Title}"
                               TextColor="{StaticResource LightTextColor}"
                               FontSize="Body"
                               VerticalTextAlignment="Center"
                               HorizontalTextAlignment="Start"
                               x:Name="_label">
                        </Label>
                    </Grid>
                </DataTemplate>
            </Shell.ItemTemplate>

            <FlyoutItem Title="Páginas" FlyoutDisplayOptions="AsMultipleItems" FlyoutIcon="factorpro.png">
                <ShellContent
                    Title="Calcular Aditivo"
                    ContentTemplate="{DataTemplate local:Page1}"
                    Route="Page1"
                    IsVisible="True"
                    Icon="aditivo.png"/>

                <ShellContent
                    Title="Gerar Contrato"
                    ContentTemplate="{DataTemplate local:ContratoCarousel}"
                    Route="ContratoCarousel" 
                    Icon="contrato.png"/>

                <ShellContent
                    Title="Clientes/Sacados"
                    ContentTemplate="{DataTemplate local:MainPage}"
                    Route="MainPage"
                    IsEnabled="False"
                    IsVisible="False"
                    Icon="clientesacado.png"/>
            </FlyoutItem>
        </Grid>

        <!-- 全局加载Frame -->
        <Frame 
            BackgroundColor="#80000000"
            IsVisible="{Binding Source={x:Static local:LoadingViewModel.Instance}, Path=IsVisible}"
            CornerRadius="0"
            Padding="0"
            Margin="0">
            <VerticalStackLayout
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Spacing="10">
                <ProgressBar 
                    IsRunning="True"
                    WidthRequest="200"
                    Color="{StaticResource Primary}"/>
                <Label 
                    Text="{Binding Source={x:Static local:LoadingViewModel.Instance}, Path=LoadingText}"
                    TextColor="White"
                    FontSize="Body"/>
            </VerticalStackLayout>
        </Frame>
    </Grid>
</Shell>

3. 在任意页面控制加载状态

直接调用单例ViewModel即可在任意页面控制加载框的显隐和文本:

namespace Mobile
{
    public partial class Page1 : ContentPage
    {
        private readonly LoadingViewModel _loadingVm = LoadingViewModel.Instance;

        public Page1()
        {
            InitializeComponent();
        }

        private async void StartOperation_Clicked(object sender, EventArgs e)
        {
            // 显示加载框并自定义文本
            _loadingVm.LoadingText = "正在计算添加剂...";
            _loadingVm.IsVisible = true;

            // 模拟耗时业务操作
            await Task.Delay(3000);

            // 隐藏加载框
            _loadingVm.IsVisible = false;
        }
    }
}

核心优势

  • 无需拆分内容页,利用Shell根容器实现全局覆盖
  • 单例ViewModel保证状态全局同步,无需页面间传递数据
  • 数据绑定自动同步UI状态,避免手动操作控件

内容的提问来源于stack exchange,提问作者Heitor Badotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 12:13:13