执行后处理 ReactiveCommand

Dispose of ReactiveCommand after execution

我正在使用 System.Windows.Interactivity 绑定 LoadedCommand,如下所示:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

在我的视图模型中,我在加载视图时加载数据:

LoadedCommand = ReactiveCommand.CreateFromTask(LoadData);

我的问题是Loaded事件实际上被父视图触发了多次。我想在第一次执行后停止 LoadedCommand 而不做类似的事情:

async Task LoadData()
{
    if (didLoad) return;
    ...
}

在 LoadData 方法中将命令设置为空。所以你不需要为此维护一个单独的标志。

async Task LoadData()
{
    // your logic goes here
    LoadedCommand = null;
}

这是一个棘手的问题,因为加载处理程序被调用了多次。这很烦人。所以我们有一些帮助代码来解决这个问题。

using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Windows;

namespace Utils
{
    public static class FrameworkElementExtensions
    {
        public static void LoadUnloadHandler
            ( this FrameworkElement control
            , Func<IDisposable> action)
        {
            var state = false;
            var cleanup = new SerialDisposable();
            Observable.Merge
                (Observable.Return(control.IsLoaded)
                    , control.Events().Loaded.Select(x => true)
                    , control.Events().Unloaded.Select(x => false)
                )
                .Subscribe(isLoadEvent =>
                {
                    if (!state)
                    {
                        // unloaded state
                        if (isLoadEvent)
                        {
                            state = true;
                            cleanup.Disposable = 
                                new CompositeDisposable(action());
                        }
                    }
                    else
                    {
                        // loaded state
                        if (!isLoadEvent)
                        {
                            state = false;
                            cleanup.Disposable = Disposable.Empty;
                        }
                    }

                });
        }


    }
}

代码处理LoadUnload事件,过滤掉多次调用问题。这个想法是你提供一个回调,它在 Load 和 returns 上执行一些操作,一个 IDisposable 将在 上处理]卸载.

例如,如果您需要注册到网络连接等外部资源,但只有当控件可见时,您才可以在构造函数后面的代码中执行。

this.LoadUnloadHandler(()=>{
    MyViewModel.Connect();
    return Disposable.Create(()=>MyViewModel.Disconnect());
});

类 / 使用的库