MVVM模式中,BaseViewModel 的 IsBusy 属性的作用

MVVM模式中,BaseViewModel 的 IsBusy 属性的作用

在MVVM模式中,BaseViewModel 的 IsBusy 属性主要用于管理ViewModel的异步操作状态,确保界面与后台任务的协调。以下是其核心用途和实现细节:


1. 核心作用

  • 防止重复操作

    当异步任务(如网络请求、数据库查询)执行时,将 IsBusy 设为 true,禁用按钮或控件,避免用户重复触发。

  • UI状态反馈

    在界面显示加载动画(如旋转图标、进度条),提示用户操作正在进行中。

  • 统一状态管理

    作为基类属性,所有继承的ViewModel均可复用,减少重复代码。


2. 典型使用场景

csharp 复制代码
// 在 BaseViewModel 中定义
public class BaseViewModel : INotifyPropertyChanged 
{
    private bool _isBusy;
    public bool IsBusy 
    {
        get => _isBusy;
        set 
        {
            _isBusy = value;
            OnPropertyChanged();
            // 触发命令可执行性更新(如按钮禁用)
            OnPropertyChanged(nameof(IsNotBusy)); 
        }
    }
    
    // 方便绑定反向逻辑(如按钮的 IsEnabled)
    public bool IsNotBusy => !IsBusy;

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string name = null) 
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
  • 绑定到界面控件

    xml 复制代码
    <Button Text="加载数据" 
            Command="{Binding LoadDataCommand}" 
            IsEnabled="{Binding IsNotBusy}"/>
    <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="True"/>
  • 异步操作中的状态管理

    csharp 复制代码
    public class UserViewModel : BaseViewModel 
    {
        public ICommand LoadDataCommand => new Command(async () => 
        {
            if (IsBusy) return; // 防止重复执行
    
            IsBusy = true;
            try 
            {
                await LoadDataAsync(); // 异步任务
            }
            finally 
            {
                IsBusy = false; // 确保状态重置
            }
        });
    }

3. 高级优化

  • 计数器模式

    处理多个并发任务时,使用计数器代替布尔值:

    csharp 复制代码
    private int _busyCounter;
    public bool IsBusy 
    {
        get => _busyCounter > 0;
        set 
        {
            _busyCounter = Math.Max(0, value ? _busyCounter + 1 : _busyCounter - 1);
            OnPropertyChanged();
        }
    }
  • 附加状态信息

    扩展 BusyMessage 属性,提供更详细的提示:

    csharp 复制代码
    private string _busyMessage;
    public string BusyMessage 
    {
        get => _busyMessage;
        set 
        {
            _busyMessage = value;
            OnPropertyChanged();
        }
    }
    
    // 使用时:
    IsBusy = true;
    BusyMessage = "正在加载用户数据...";

4. 注意事项

  • 线程安全

    异步操作可能在其他线程修改 IsBusy,需确保通过 Dispatcher 或 MainThread.BeginInvokeOnMainThread(Xamarin)更新UI属性。

  • 异常处理

    在 try/catch/finally 中确保 IsBusy 被正确重置,避免任务异常后界面"卡死"。


通过 IsBusy,MVVM模式实现了业务逻辑与UI状态的解耦,提升代码可维护性,同时增强用户体验。

相关推荐
用户7884773163417 小时前
WinForms 迁移 WPF:Upgrade Assistant 覆盖 30%,剩下 70% 我手写了六周
c#
寂寞的船21 小时前
【Unity知识速递】第13期 Unity 内存泄漏排查实战:从 Memory Profiler 到 Lua 引用泄漏的生产级全链路诊断
unity·junit·c#·游戏引擎·lua
用户3721574261352 天前
C# 提取 PDF 附件:包括文档附件和页面注释附件
c#
寂寞的船2 天前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
huaqianzkh3 天前
WinForm C#:循环修改控件UI闪烁卡顿?SuspendLayout / ResumeLayout 与 BeginUpdate 优化
开发语言·ui·c#
用户3721574261354 天前
C# 实现 Excel 单元格保护:锁定公式并允许编辑指定区域
c#·ai编程·编程语言
公子小六4 天前
基于.NET的Windows窗体编程之WinForms数据持久化(1)
windows·microsoft·c#·.net·winforms
三雷科技4 天前
第6章第4节:自定义分词器
开发语言·c#
zhanghaha13144 天前
C# 系列教程_12 字符串 string 保姆级系统教程(面向新手,大量示例 + 原理讲解)
开发语言·数据库·c#
Coder_Shenshen5 天前
罗克韦尔ACD工程归档离线变量树解析
算法·c#