简体   繁体   English

Caliburn Micro:如何在 Windows 手机 silverlight 中导航

[英]Caliburn Micro: how to navigate in Windows phone silverlight

i am trying to use Caliburn Micro in my windows phone 7 project.我正在尝试在我的 windows 手机 7 项目中使用 Caliburn Micro。 But i got a nullreferenceexception when navigate the page.但是在导航页面时我得到了一个 nullreferenceexception。

namespace Caliburn.Micro.HelloWP7 {
    public class MainPageViewModel {
        readonly INavigationService navigationService;

        public MainPageViewModel(INavigationService navigationService) {
            this.navigationService = navigationService;
        }

        public void GotoPageTwo() {
            /*navigationService.UriFor<PivotPageViewModel>()
                .WithParam(x => x.NumberOfTabs, 5)
                .Navigate();*/
            navigationService.UriFor<Page1ViewModel>().Navigate();
        }
    }
}

namespace Caliburn.Micro.HelloWP7
{
    public class Page1ViewModel
    {
         readonly INavigationService navigationService;

         public Page1ViewModel(INavigationService navigationService)
         {
            this.navigationService = navigationService;
        }
    }
}

can anyone tell me what's the problem of my code?谁能告诉我我的代码有什么问题? thanks in advance.提前致谢。

here is bootstrapper:这是引导程序:

public class ScheduleBootstrapper : PhoneBootstrapper
{
    PhoneContainer container;

    protected override void Configure()
    {
        container = new PhoneContainer(RootFrame);

        container.RegisterPhoneServices();
        container.PerRequest<MainPageViewModel>();
        container.PerRequest<MainContentViewModel>();
        container.PerRequest<Page1ViewModel>();
        AddCustomConventions();
    }

    static void AddCustomConventions()
    {
        ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding =
            (viewModelType, path, property, element, convention) =>
            {
                if (ConventionManager
                    .GetElementConvention(typeof(ItemsControl))
                    .ApplyBinding(viewModelType, path, property, element, convention))
                {
                    ConventionManager
                        .ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
                    ConventionManager
                        .ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType);
                    return true;
                }

                return false;
            };

        ConventionManager.AddElementConvention<Panorama>(Panorama.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding =
            (viewModelType, path, property, element, convention) =>
            {
                if (ConventionManager
                    .GetElementConvention(typeof(ItemsControl))
                    .ApplyBinding(viewModelType, path, property, element, convention))
                {
                    ConventionManager
                        .ConfigureSelectedItem(element, Panorama.SelectedItemProperty, viewModelType, path);
                    ConventionManager
                        .ApplyHeaderTemplate(element, Panorama.HeaderTemplateProperty, viewModelType);
                    return true;
                }

                return false;
            };
    }

    protected override object GetInstance(Type service, string key)
    {
        return container.GetInstance(service, key);
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance)
    {
        container.BuildUp(instance);
    }
}

I had this too, and tracked it down as follows:我也有这个,并跟踪如下:

As you know, Caliburn.Micro uses convention-over-configuration to locate Views for ViewModels, and vice-versa, which means we need to follow the conventions.如您所知,Caliburn.Micro 使用约定优于配置来定位 ViewModel 的视图,反之亦然,这意味着我们需要遵循约定。 My mistake was to have the namespace 's inconsistent for the View and ViewModel我的错误是 View 和 ViewModel 的namespace不一致

In my case, I had就我而言,我有

MyWP7App.DetailsViewModel , and MyWP7App.DetailsViewModel

MyWP7App.Views.DetailsView

--> I renamed the VM's namespace to be MyWP7App.ViewModels.DetailsViewModel , and it worked out fine. --> 我将 VM 的命名空间重命名为MyWP7App.ViewModels.DetailsViewModel ,结果很好。 I think I could have moved the view into MyWP7App.DetailsView for a good result, too...我也可以将视图移到MyWP7App.DetailsView以获得良好的结果......


Under the covers在被子下

the call to Navigate() invokes DeterminePageName() which, in turn, invokes ViewLocator.LocateTypeForModelTypeNavigate()的调用会调用 DeletePageName DeterminePageName() ,后者又会调用ViewLocator.LocateTypeForModelType

This, like the rest of CM is overridable, but the default implementation looks like this:这个和CM的rest一样是可以覆盖的,但是默认实现是这样的:

public static Func<Type, DependencyObject, object, Type> LocateTypeForModelType = (modelType, displayLocation, context) => {
    var viewTypeName = modelType.FullName.Substring(
        0,
        modelType.FullName.IndexOf("`") < 0
            ? modelType.FullName.Length
            : modelType.FullName.IndexOf("`")
        );

    Func<string, string> getReplaceString;
    if (context == null) {
        getReplaceString = r => { return r; };
    }
    else {
        getReplaceString = r => {
            return Regex.Replace(r, Regex.IsMatch(r, "Page$") ? "Page$" : "View$", ContextSeparator + context);
        };
    }

    var viewTypeList = NameTransformer.Transform(viewTypeName, getReplaceString);
    var viewType = (from assembly in AssemblySource.Instance
                    from type in assembly.GetExportedTypes()
                    where viewTypeList.Contains(type.FullName)
                    select type).FirstOrDefault();

    return viewType;
};

If you follow the debugger through, you end up with a collection viewTypeList that contains MyWP7App.DetailsView , and a type whose full name is MyWP7App.Views.DetailsView , and the viewType returned is therefore null... this is the cause of the NullReferenceException.如果您按照调试器进行操作,您最终会得到一个集合viewTypeList ,其中包含MyWP7App.DetailsView和一个全名为MyWP7App.Views.DetailsView的类型,因此返回的viewType是 null ......这是 NullReferenceException 的原因.

I'm 99% sure the NameTransformer.Transform call will perform a pattern-match and transform the ViewModels in the namespace of the VM to Views in the namespace of the View it's trying to locate...我 99% 确定NameTransformer.Transform调用将执行模式匹配并将 VM 命名空间中的ViewModels转换为它试图定位的 View 命名空间中的Views ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Windows Phone中带有Caliburn Micro的弹出窗口 - Popup with Caliburn Micro in Windows Phone 如何使用Caliburn.Micro for Windows Phone修改共享对象 - How to modify a shared object with Caliburn.Micro for Windows Phone Windows Phone Caliburn Micro HyperLink单击事件 - Windows Phone Caliburn Micro HyperLink click event 使用Caliburn.Micro在Windows Phone上进行Facebook身份验证回调 - Facebook authentication callback on Windows Phone using Caliburn.Micro Caliburn Micro:在Windows Phone模板中找不到方法的目标 - Caliburn Micro: no target found for method in Windows Phone template 返回到viewmodel禁用canexcute命令(Caliburn Micro-Windows Phone 8.1) - Return to viewmodel disables canexcute of commands (Caliburn Micro - Windows Phone 8.1) Caliburn.Micro 2.0并在Windows Phone 8.1 XAML中导航 - Caliburn.Micro 2.0 and navigating back in Windows Phone 8.1 XAML ListBox中的项目选择错误(Windows Phone,Caliburn.Micro,Rx) - Wrong item selection in ListBox (Windows Phone, Caliburn.Micro, Rx) 在Windows Phone 8.1上使用单个View查看多个ViewModel和Caliburn.Micro - Using single View for multiple ViewModels with Caliburn.Micro on Windows Phone 8.1 Windows Phone 7.x上的Caliburn Micro中的OnActivate事件发生后的奇怪异常 - Strange exception after OnActivate event in Caliburn Micro on Windows Phone 7.x
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM