不处理视图或视图模型的棱镜区域
Prism Regions Not Disposing Views or ViewModels
我假设 Prism 区域会自动检测并调用 Dispose
实现 IDisposable
接口的任何视图或视图模型。结果我错了。
然后我考虑实施 IActiveAware
,这样我就可以自己处理我的 views/viewmodels,但这似乎有点老套。我宁愿让它自动完成。
如何配置 Prism 区域以自动处理实现 IDisposable
的视图和视图模型?
在互联网上广泛搜索后,没有找到任何真正的解决方案,我开发了自己的自定义 RegionBehavior
,结果证明效果很好。
该行为侦听区域的视图集合是否有任何更改,当任何更改被删除时,它会检查并调用视图and/or 上的Dispose
] 查看模型,只有当他们实现 IDisposable
.
class DisposeClosedViewsBehavior : RegionBehavior
{
protected override void OnAttach()
{
Region.Views.CollectionChanged += Views_CollectionChanged;
}
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Remove) return;
foreach (var removedView in e.OldItems)
{
IDisposable disposableView = removedView as IDisposable;
IDisposable disposableViewModel;
var iviewView = removedView as IView;
if (iviewView != null)
{
disposableViewModel = iviewView.DataContext as IDisposable;
}
else
{
var frameworkElementView = removedView as FrameworkElement;
disposableViewModel = frameworkElementView?.DataContext as IDisposable;
}
disposableView?.Dispose();
disposableViewModel?.Dispose();
}
}
}
最后一步是通过覆盖引导程序 ConfigureDefaultRegionBehaviors
方法将此行为插入 prism:
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
var factory = base.ConfigureDefaultRegionBehaviors();
factory.AddIfMissing(nameof(DisposeClosedViewsBehavior), typeof(DisposeClosedViewsBehavior));
return factory;
}
很有魅力!
修改 Nathan A
对 Prism 6 的回答(IView
已删除)并使用方便的内置辅助方法来调用 Dispose View 和 ViewModel。
class DisposeClosedViewsBehavior : RegionBehavior
{
protected override void OnAttach() =>
Region.Views.CollectionChanged += Views_CollectionChanged;
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (!(e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace))
return;
foreach (var removedView in e.OldItems)
MvvmHelpers.ViewAndViewModelAction<IDisposable>(removedView, d => d.Dispose());
}
}
我假设 Prism 区域会自动检测并调用 Dispose
实现 IDisposable
接口的任何视图或视图模型。结果我错了。
然后我考虑实施 IActiveAware
,这样我就可以自己处理我的 views/viewmodels,但这似乎有点老套。我宁愿让它自动完成。
如何配置 Prism 区域以自动处理实现 IDisposable
的视图和视图模型?
在互联网上广泛搜索后,没有找到任何真正的解决方案,我开发了自己的自定义 RegionBehavior
,结果证明效果很好。
该行为侦听区域的视图集合是否有任何更改,当任何更改被删除时,它会检查并调用视图and/or 上的Dispose
] 查看模型,只有当他们实现 IDisposable
.
class DisposeClosedViewsBehavior : RegionBehavior
{
protected override void OnAttach()
{
Region.Views.CollectionChanged += Views_CollectionChanged;
}
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Remove) return;
foreach (var removedView in e.OldItems)
{
IDisposable disposableView = removedView as IDisposable;
IDisposable disposableViewModel;
var iviewView = removedView as IView;
if (iviewView != null)
{
disposableViewModel = iviewView.DataContext as IDisposable;
}
else
{
var frameworkElementView = removedView as FrameworkElement;
disposableViewModel = frameworkElementView?.DataContext as IDisposable;
}
disposableView?.Dispose();
disposableViewModel?.Dispose();
}
}
}
最后一步是通过覆盖引导程序 ConfigureDefaultRegionBehaviors
方法将此行为插入 prism:
protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors()
{
var factory = base.ConfigureDefaultRegionBehaviors();
factory.AddIfMissing(nameof(DisposeClosedViewsBehavior), typeof(DisposeClosedViewsBehavior));
return factory;
}
很有魅力!
修改 Nathan A
对 Prism 6 的回答(IView
已删除)并使用方便的内置辅助方法来调用 Dispose View 和 ViewModel。
class DisposeClosedViewsBehavior : RegionBehavior
{
protected override void OnAttach() =>
Region.Views.CollectionChanged += Views_CollectionChanged;
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (!(e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace))
return;
foreach (var removedView in e.OldItems)
MvvmHelpers.ViewAndViewModelAction<IDisposable>(removedView, d => d.Dispose());
}
}