簡體   English   中英

Caliburn Micro:如何在 Windows 手機 silverlight 中導航

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

我正在嘗試在我的 windows 手機 7 項目中使用 Caliburn Micro。 但是在導航頁面時我得到了一個 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;
        }
    }
}

誰能告訴我我的代碼有什么問題? 提前致謝。

這是引導程序:

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);
    }
}

我也有這個,並跟蹤如下:

如您所知,Caliburn.Micro 使用約定優於配置來定位 ViewModel 的視圖,反之亦然,這意味着我們需要遵循約定。 我的錯誤是 View 和 ViewModel 的namespace不一致

就我而言,我有

MyWP7App.DetailsViewModel

MyWP7App.Views.DetailsView

--> 我將 VM 的命名空間重命名為MyWP7App.ViewModels.DetailsViewModel ,結果很好。 我也可以將視圖移到MyWP7App.DetailsView以獲得良好的結果......


在被子下

Navigate()的調用會調用 DeletePageName DeterminePageName() ,后者又會調用ViewLocator.LocateTypeForModelType

這個和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;
};

如果您按照調試器進行操作,您最終會得到一個集合viewTypeList ,其中包含MyWP7App.DetailsView和一個全名為MyWP7App.Views.DetailsView的類型,因此返回的viewType是 null ......這是 NullReferenceException 的原因.

我 99% 確定NameTransformer.Transform調用將執行模式匹配並將 VM 命名空間中的ViewModels轉換為它試圖定位的 View 命名空間中的Views ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM