Caliburn Micro ActivateItem无法更新绑定

时间:2017-08-01 13:12:40

标签: wpf binding converter caliburn.micro

考虑一个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应用程序所发生的事情

有没有办法确保在没有:

的情况下刷新这些绑定
  • 在SomeViewModel的Refresh()中调用OnActivate()
  • 在EventAgregator上发布将在SomeViewModel中处理的事件,该事件将调用Refresh()

1 个答案:

答案 0 :(得分:0)

这是因为视图缓存:Conductor<T>Screen,而ScreenViewAware。该类旨在缓存视图实例:您会注意到,在您的视图模型之间来回导航时,第一个视图中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);
    };
}