我在MEF应用程序中遇到了一个有趣的情况。主工作区是在ContentControl上注册的区域,一次只有一个活动视图。设置和导航工作正常。现在我观察到的是,当我更改此 MainRegion 上的视图时,我再次评估了对viewmodel的所有绑定。
为了检查这个,我在我的视图模型上添加了一个计数器,以查看它的加载频率。当我改变视图A - >查看B - >查看A,然后计数器将是3:
我正在使用普通电话激活某个地区:
region.Activate(view);
调试此问题时,我看到在激活区域时,旧区域被取消激活,最终设置
ContentControl.Content = null;
这似乎修改了可视化树并重新评估旧视图上的所有绑定。
它似乎是MEF和WPF问题的混合体。有没有办法阻止在激活新区域时评估绑定,或者在WPF端阻止在ContentControl.Content变为null时重新评估绑定?
我发现了一个类似的问题,但没有回答: WPF: disable bindings update on detach
答案 0 :(得分:1)
此问题似乎是ContentControl本身的问题,请参阅此帖子以获取更多信息:http://blogs.microsoft.co.il/tomershamam/2009/09/11/wpf-performance-sweets-contentcontrolcontent-null/
要避免在区域中的视图之间切换时出现性能问题,可以使用该区域的另一个控件将视图保留在可视树中。用修改后的ContentControl
替换ItemsControl
。我在这篇文章中找到了一个解决方案:https://vslepakov.blogspot.de/2014/09/navigate-faster-with-prism-and-wpf.html。它可以隐藏旧视图并显示新视图。
我修改了这个例子:
public class RegionItemsControl : ItemsControl
{
protected override bool IsItemItsOwnContainerOverride(object item)
{
return false;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
((ContentPresenter)element).ContentTemplate = ItemTemplate;
}
}
将其添加到您的shell并将其标记为区域:
<controls:RegionItemsControl
prism:RegionManager.RegionName="MainRegion">
<controls:RegionItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</controls:RegionItemsControl.ItemsPanel>
<controls:RegionItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"/>
</DataTemplate>
</controls:RegionItemsControl.ItemTemplate>
</controls:RegionItemsControl>
导航由事件处理,触发以下代码:
private FrameworkElement _lastView = null;
private bool LoadAndActivateWorkspaceAreaView(Type requestedViewType, IRegion region)
{
var viewToActivate = region.Views.FirstOrDefault(viewItem => viewItem.GetType() == requestedViewType) as FrameworkElement;
if (viewToActivate == null)
{
viewToActivate = MefContainer.GetExportedValue(requestedViewType) as FrameworkElement;
if (viewToActivate == null)
throw new InvalidOperationException("view not found!");
viewToActivate.Visibility = Visibility.Collapsed;
region.Add(viewToActivate); // Adds new view to RegionItemsControl
}
if (_lastView != null)
_lastView.Visibility = Visibility.Collapsed;
_lastView = viewToActivate;
_lastView.Visibility = Visibility.Visible;
}
此解决方案的一个问题是,在向区域添加新视图时,会重新评估存储在RegionItemsControl
中的“旧”视图的绑定。这似乎是我认为ItemsControl
的一个问题。