如何在 dotnet Maui 中实现活动/等待指示器?

bal*_*ntn 4 activity-indicator maui

我需要为我的毛伊岛应用程序中的页面实现一个等待指示器。

搜索给了我这个,但没有逐步说明。

那么我该怎么做呢?

bal*_*ntn 6

概述:

  • 显示动画的控件称为 ActivityIndi​​cator。
  • ActivityIndi​​cator 是一个视觉元素,应该是页面的一部分。
    因此,将 ActivityIndi​​cator 添加到您的 xaml 中。
  • 指示器的状态是逻辑的一部分 - 应该存在于您的视图模型中。
    因此,向视图模型添加一个可绑定属性,并将 ActivityIndi​​cator.IsRunning 绑定到该属性。

示例(我没有测试,仅用于说明)
页面(xaml):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:customcontrols="clr-namespace:Waiter.Maui.CustomControls"
             x:Class="..." >

    <ContentPage.Content>
        <ActivityIndicator IsRunning="{Binding IsBusy}" />
        <Button Text="Go" Command="{Binding GoCommand}" />
    </ContentPage.Content>
</ContentPage>
Run Code Online (Sandbox Code Playgroud)

视图模型:

namespace MyNamespace
{
    public class MyViewModel : BaseViewModel
    {
        public MyViewModel()
        {
            GoCommand = new Command(execute: OnGo, canExecute: true);
        }

        public Command GoCommand { get; }
        private void OnGo()
        {
            MainThread.InvokeOnMainThreadAsync(async () =>
            {
                IsBusy = true;
                Thread.Sleep(5000);
                IsBusy = false;
                return result;
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

BaseViewModel 类(以便可以从现有社区内容中重用它):

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

namespace Waiter.Maui.Pages
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        bool isBusy = false;
        public bool IsBusy
        {
            get { return isBusy; }
            set { SetProperty(ref isBusy, value); }
        }

        string title = string.Empty;
        public string Title
        {
            get { return title; }
            set { SetProperty(ref title, value); }
        }

        protected bool SetProperty<T>(ref T backingStore, T value,
            [CallerMemberName] string propertyName = "",
            Action onChanged = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingStore, value))
                return false;

            backingStore = value;
            onChanged?.Invoke();
            OnPropertyChanged(propertyName);
            return true;
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;

            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)