考虑一个ShellViewModel : Conductor<T>.Collection.OneActive
,其中我有2个通过PropertyInjection注入的ViewModel。所以这些viewmodel总是有相同的实例。
public SomeViewModel SomeViewModel {get; set;}
public AnotherViewModel AnotherViewModel {get; set;}
SomeViewModel有一个TextBlock,它将Text绑定到一个属性(使用NotifyPropertyChanged)并附加了一个转换器。
ActivateItem(someViewModel)
时,我会输入SomeView.xaml
中定义的转换器。ActivateItem(AnotherViewModel)
并再次ActivateItem(SomeViewModel)
,我就不会进入此转换器。我希望调用ActivateItem会一直更新绑定并再次执行转换器,或者我做错了什么?
我知道没有任何内容更改为属性本身,并且未调用NotifyPropertyChanged。但我希望可视化用户控件会刷新绑定。 据我所知,这是没有Caliburn.Micro的老式WPF应用程序所发生的事情
有没有办法确保在没有:
的情况下刷新这些绑定Refresh()
中调用OnActivate()
Refresh()
答案 0 :(得分:0)
这是因为视图缓存:Conductor<T>
是Screen
,而Screen
是ViewAware
。该类旨在缓存视图实例:您会注意到,在您的视图模型之间来回导航时,第一个视图中ScrollViewer
的位置将保持不变,即使它不受约束任何财产。
您可以覆盖视图模型的GetView(object)
方法,如下所示:
public override object GetView(object context = null)
{
return null;
}
这实际上会禁用视图缓存。
或者,您可以修改视图位置的代码以满足您的需要。只需将此添加到您的bootstrapper启动:
private void CustomizeViewLocation()
{
var log = LogManager.GetLog(typeof(ViewLocator));
ViewLocator.LocateForModel = (model, displayLocation, context) => {
// Either remove the IViewAware handling to completely disable
// view caching...
var viewAware = model as IViewAware;
if (viewAware != null)
{
var view = viewAware.GetView(context) as UIElement;
if (view != null)
{
// Or add this custom code to always refresh...
var propertyChangedBase = model as PropertyChangedBase;
if (propertyChangedBase != null)
{
propertyChangedBase.Refresh();
}
// End custom code.
var windowCheck = view as Window;
if (windowCheck == null || (!windowCheck.IsLoaded && !(new WindowInteropHelper(windowCheck).Handle == IntPtr.Zero)))
{
log.Info("Using cached view for {0}.", model);
return view;
}
}
}
return ViewLocator.LocateForModelType(model.GetType(), displayLocation, context);
};
}