WPF UI标准流水线

复制代码
流水线基类
cs 复制代码
    public class ViewModelBase : INotifyPropertyChanged
    {
        protected readonly TaskScheduler _uiScheduler;

        public ViewModelBase()
        {
            _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        /// <summary>
        /// UI标准流水线:捕获状态→后台任务→更新UI→恢复状态
        /// </summary>
        protected void ExecuteWithUiPipeline<TState, TResult>(
            Func<TState> captureState,
            Func<TState, TResult> backgroundWork,
            Action<TResult> updateUi,
            Action<TState> restoreUi,
            Action<bool> busyFlagSetter)
        {
            busyFlagSetter(true);
            var state = captureState();

            Task.Factory.StartNew(() => backgroundWork(state))
            .ContinueWith(task =>
            {
                try
                {
                    if (task.Exception != null)
                    {
                        var ex = task.Exception.InnerException ?? task.Exception;
                        MessageBox.Show("操作异常:" + ex.Message);
                        return;
                    }
                    var result = task.Result;
                    updateUi(result);
                    restoreUi(state);
                }
                finally
                {
                    busyFlagSetter(false);
                }
            }, _uiScheduler);
        }
    }

子类使用示例

cs 复制代码
public class TreeViewModel : ViewModelBase
{
    private bool _isBusy;
    public bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged(nameof(IsBusy)); } }

    public void RefreshTree()
    {
        // 定义捕获状态
        Func<TreeState> capture = () => new TreeState
        {
            SelectedId = FindSelectedNode(TreeRoot)?.Id ?? -1,
            ExpandedIds = GetExpandedIds(TreeRoot)
        };

        // 后台工作
        Func<TreeState, List<NodeModel>> work = state => LoadDataFromDb();

        // 更新UI
        Action<List<NodeModel>> update = data =>
        {
            TreeRoot = new ObservableCollection<NodeViewModel>(BuildTree(data));
        };

        // 恢复状态
        Action<TreeState> restore = state =>
        {
            RestoreState(TreeRoot, state.SelectedId, state.ExpandedIds);
        };

        // 执行流水线
        ExecuteWithUiPipeline(capture, work, update, restore, busy => IsBusy = busy);
    }
}

🧠 总结

ViewModelBase 提供的这个流水线方法,本质上是将WPF异步编程中反复出现的"线程切换 + 状态管理"模式抽象为一个可复用的基础设施。它让子类代码更简洁、更聚焦于业务,同时保证了UI线程安全。你只需要在子类中实现具体的状态捕获、后台任务和UI恢复逻辑,框架自动帮你处理调度和异常。

如果你还想加入防重入版本号 功能,可以在子类中扩展,或者在ExecuteWithUiPipeline的基础上再封装一层,传入一个Func<bool>检查是否可以执行,或者集成CancellationToken。这个基类为更高级的封装提供了良好的起点。

相关推荐
阿部多瑞 ABU17 小时前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
MoSTChillax2 天前
UI规范设计:从视觉到交互的全面指南
前端·ui·产品经理·设计规范·vibecoding
FuckPatience2 天前
WPF 给一个界面上的按钮应用同一种样式
wpf
Devlab2 天前
LVGL设计大师——网页版anyui来了!!
嵌入式硬件·物联网·低代码·ui·iot
向星而行_star3 天前
Ito 模型在业务场景中的落地应用指南
ui
界面开发小八哥3 天前
界面控件DevExpress XAF v26.1新版亮点——Blazor UI功能增强(二)
ui·界面控件·blazor·devexpress·ui开发
Oll Correct3 天前
Adobe illustrator 案例四:吃豆人 (Pac-Man)图标绘制
笔记·ui·adobe·illustrator
Polevne3 天前
WPF\MAUI\Avalonia Dispatcher
wpf
Ares-Wang3 天前
wpf 图表制作 LiveCharts
wpf
阿图灵3 天前
Agentic AI 架构入门(九):Agent 通信协议全景——ACP/A2A/AG-UI/MCP
人工智能·ui·架构·ai agent·智能体·mcp·agentic ai