如何在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
相关产品推荐
相关产品推荐

