执行后处理 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;
}
}
});
}
}
}
代码处理Load和Unload事件,过滤掉多次调用问题。这个想法是你提供一个回调,它在 Load 和 returns 上执行一些操作,一个 IDisposable 将在 上处理]卸载.
例如,如果您需要注册到网络连接等外部资源,但只有当控件可见时,您才可以在构造函数后面的代码中执行。
this.LoadUnloadHandler(()=>{
MyViewModel.Connect();
return Disposable.Create(()=>MyViewModel.Disconnect());
});
类 / 使用的库
我正在使用 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;
}
}
});
}
}
}
代码处理Load和Unload事件,过滤掉多次调用问题。这个想法是你提供一个回调,它在 Load 和 returns 上执行一些操作,一个 IDisposable 将在 上处理]卸载.
例如,如果您需要注册到网络连接等外部资源,但只有当控件可见时,您才可以在构造函数后面的代码中执行。
this.LoadUnloadHandler(()=>{
MyViewModel.Connect();
return Disposable.Create(()=>MyViewModel.Disconnect());
});
类 / 使用的库