Xamarin.Forms 和 Caliburn.Micro 的 WinPhone 8.1 项目无法创建视图
WinPhone 8.1 project with Xamarin.Forms and Caliburn.Micro failes to create view
我有一个 Xamarin.Forms 项目和一个使用 Caliburn.Micro.
的 WinPhone 8.1 项目
这是我的 App.xaml:
<caliburn:CaliburnApplication x:Class="MyProject.WinPhone.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:caliburn="using:Caliburn.Micro"
xmlns:local="using:MyProject.WinPhone" />
这是我的 App.xaml.cs:
public sealed partial class App : Caliburn.Micro.CaliburnApplication
{
private WinRTContainer container;
private TransitionCollection transitions;
public App()
{
InitializeComponent();
}
protected override void Configure()
{
container = new WinRTContainer();
container.RegisterWinRTServices();
//TODO: Register your view models at the container
container.PerRequest<MainViewModel>();
}
protected override object GetInstance(Type service, string key)
{
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new Exception("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override void PrepareViewFirst(Frame rootFrame)
{
container.RegisterNavigationService(rootFrame);
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[] { typeof(MainViewModel).GetTypeInfo().Assembly, typeof(Windows.Foundation.AsyncActionCompletedHandler).GetTypeInfo().Assembly };
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
if (args.PreviousExecutionState == ApplicationExecutionState.Running)
return;
try
{
DisplayRootView<MainView>();
//DisplayRootView<MainPage>();
//DisplayRootViewFor<MainViewModel>();
}
catch (Exception ex)
{
var x = 8;
throw;
}
}
}
这些是 NuGet 包:
它可以编译,但是当我尝试 运行 它时,我在 DisplayRootView
处得到以下异常:
Could not find Windows Runtime type
'Windows.Foundation'.":"Windows.Foundation
at System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(String typeName, Boolean& isPrimitive)
at System.StubHelpers.SystemTypeMarshaler.ConvertToManaged(TypeNameNative* pNativeType, Type& managedType)
at Windows.UI.Xaml.Controls.Frame.Navigate(Type sourcePageType, Object parameter)
at Caliburn.Micro.CaliburnApplication.DisplayRootView(Type viewType, Object paramter)
at Caliburn.Micro.CaliburnApplication.DisplayRootView[T](Object parameter)
at MyProject.WinPhone.App.OnLaunched(LaunchActivatedEventArgs args)
你能告诉我我应该怎么做吗?
更新:
问题的根源在于这部分代码:
private global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider _provider;
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlType(global::System.Type type)
{
if(_provider == null)
{
_provider = new global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider();
}
return _provider.GetXamlTypeByType(type);
}
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlType(string fullName)
{
if(_provider == null)
{
_provider = new global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider();
}
return _provider.GetXamlTypeByName(fullName);
}
public global::Windows.UI.Xaml.Markup.XmlnsDefinition[] GetXmlnsDefinitions()
{
return new global::Windows.UI.Xaml.Markup.XmlnsDefinition[0];
}
}
}
namespace MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks", "4.0.0.0")]
internal partial class XamlTypeInfoProvider
{
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlTypeByType(global::System.Type type)
{
global::Windows.UI.Xaml.Markup.IXamlType xamlType;
if (_xamlTypeCacheByType.TryGetValue(type, out xamlType))
{
return xamlType;
}
int typeIndex = LookupTypeIndexByType(type);
if(typeIndex != -1)
{
xamlType = CreateXamlType(typeIndex);
}
var userXamlType = xamlType as global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlUserType;
if(xamlType == null || (userXamlType != null && userXamlType.IsReturnTypeStub && !userXamlType.IsLocalType))
{
global::Windows.UI.Xaml.Markup.IXamlType libXamlType = CheckOtherMetadataProvidersForType(type);
if (libXamlType != null)
{
if(libXamlType.IsConstructible || xamlType == null)
{
xamlType = libXamlType;
}
}
}
if (xamlType != null)
{
_xamlTypeCacheByName.Add(xamlType.FullName, xamlType);
_xamlTypeCacheByType.Add(xamlType.UnderlyingType, xamlType);
}
return xamlType;
}
似乎我传入的 MainView 无法转换为合适的 XAML 类型,因为 GetXamlTypeByType
returns null.
我好像 Xamarin.Forms 视图与 WinPhone 世界不兼容...好吧,如果我没记错的话,Xamarin.Forms 应该是关于抽象视图的。
我现在该怎么办?
在我仔细阅读 Xamarin Forms tutorial 如何添加 Windows Phone 8.1 应用程序并进行相应修改后,一切都按预期工作。
在我的例子中,MainPage.xaml.cs有它的原始代码,因为我没有根据教程更改它。
public sealed partial class MainPage // REMOVE ": PhonePage"
由于 Caliburn.Micro 使用 Xamarin 基础结构,因此需要执行这些步骤。
我有一个 Xamarin.Forms 项目和一个使用 Caliburn.Micro.
的 WinPhone 8.1 项目这是我的 App.xaml:
<caliburn:CaliburnApplication x:Class="MyProject.WinPhone.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:caliburn="using:Caliburn.Micro"
xmlns:local="using:MyProject.WinPhone" />
这是我的 App.xaml.cs:
public sealed partial class App : Caliburn.Micro.CaliburnApplication
{
private WinRTContainer container;
private TransitionCollection transitions;
public App()
{
InitializeComponent();
}
protected override void Configure()
{
container = new WinRTContainer();
container.RegisterWinRTServices();
//TODO: Register your view models at the container
container.PerRequest<MainViewModel>();
}
protected override object GetInstance(Type service, string key)
{
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new Exception("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override void PrepareViewFirst(Frame rootFrame)
{
container.RegisterNavigationService(rootFrame);
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[] { typeof(MainViewModel).GetTypeInfo().Assembly, typeof(Windows.Foundation.AsyncActionCompletedHandler).GetTypeInfo().Assembly };
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
if (args.PreviousExecutionState == ApplicationExecutionState.Running)
return;
try
{
DisplayRootView<MainView>();
//DisplayRootView<MainPage>();
//DisplayRootViewFor<MainViewModel>();
}
catch (Exception ex)
{
var x = 8;
throw;
}
}
}
这些是 NuGet 包:
它可以编译,但是当我尝试 运行 它时,我在 DisplayRootView
处得到以下异常:
Could not find Windows Runtime type 'Windows.Foundation'.":"Windows.Foundation
at System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(String typeName, Boolean& isPrimitive)
at System.StubHelpers.SystemTypeMarshaler.ConvertToManaged(TypeNameNative* pNativeType, Type& managedType)
at Windows.UI.Xaml.Controls.Frame.Navigate(Type sourcePageType, Object parameter)
at Caliburn.Micro.CaliburnApplication.DisplayRootView(Type viewType, Object paramter)
at Caliburn.Micro.CaliburnApplication.DisplayRootView[T](Object parameter)
at MyProject.WinPhone.App.OnLaunched(LaunchActivatedEventArgs args)
你能告诉我我应该怎么做吗?
更新:
问题的根源在于这部分代码:
private global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider _provider;
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlType(global::System.Type type)
{
if(_provider == null)
{
_provider = new global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider();
}
return _provider.GetXamlTypeByType(type);
}
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlType(string fullName)
{
if(_provider == null)
{
_provider = new global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlTypeInfoProvider();
}
return _provider.GetXamlTypeByName(fullName);
}
public global::Windows.UI.Xaml.Markup.XmlnsDefinition[] GetXmlnsDefinitions()
{
return new global::Windows.UI.Xaml.Markup.XmlnsDefinition[0];
}
}
}
namespace MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks", "4.0.0.0")]
internal partial class XamlTypeInfoProvider
{
public global::Windows.UI.Xaml.Markup.IXamlType GetXamlTypeByType(global::System.Type type)
{
global::Windows.UI.Xaml.Markup.IXamlType xamlType;
if (_xamlTypeCacheByType.TryGetValue(type, out xamlType))
{
return xamlType;
}
int typeIndex = LookupTypeIndexByType(type);
if(typeIndex != -1)
{
xamlType = CreateXamlType(typeIndex);
}
var userXamlType = xamlType as global::MyProject.WinPhone.MyProject_WinPhone_XamlTypeInfo.XamlUserType;
if(xamlType == null || (userXamlType != null && userXamlType.IsReturnTypeStub && !userXamlType.IsLocalType))
{
global::Windows.UI.Xaml.Markup.IXamlType libXamlType = CheckOtherMetadataProvidersForType(type);
if (libXamlType != null)
{
if(libXamlType.IsConstructible || xamlType == null)
{
xamlType = libXamlType;
}
}
}
if (xamlType != null)
{
_xamlTypeCacheByName.Add(xamlType.FullName, xamlType);
_xamlTypeCacheByType.Add(xamlType.UnderlyingType, xamlType);
}
return xamlType;
}
似乎我传入的 MainView 无法转换为合适的 XAML 类型,因为 GetXamlTypeByType
returns null.
我好像 Xamarin.Forms 视图与 WinPhone 世界不兼容...好吧,如果我没记错的话,Xamarin.Forms 应该是关于抽象视图的。
我现在该怎么办?
在我仔细阅读 Xamarin Forms tutorial 如何添加 Windows Phone 8.1 应用程序并进行相应修改后,一切都按预期工作。
在我的例子中,MainPage.xaml.cs有它的原始代码,因为我没有根据教程更改它。
public sealed partial class MainPage // REMOVE ": PhonePage"
由于 Caliburn.Micro 使用 Xamarin 基础结构,因此需要执行这些步骤。