Caliburn.Micro Xamarin.Forms ViewModel 没有初始化
Caliburn.Micro Xamarin.Forms ViewModel does not initialize
我创建了一个新的 Xamarin.Forms 项目,但我在视图模型初始化方面遇到了问题。什么都没发生。我正在使用 Features 中的示例。我将示例代码修改为以下内容:
public FormsApp(SimpleContainer container)
{
//...
DisplayRootView<ConductorView>();
}
这按预期工作,但在我的项目中它根本不起作用。
我正在使用 .NET Standard 1.5(不确定这是否会导致问题)。无论如何这是我的代码
App.cs:
using System;
using Caliburn.Micro;
using Caliburn.Micro.Xamarin.Forms;
using UniversalSqlManager.ViewModels;
using Xamarin.Forms;
using INavigationService = Caliburn.Micro.Xamarin.Forms.INavigationService;
using UniversalSqlManager.Views;
namespace UniversalSqlManager
{
public class App : FormsApplication
{
private readonly SimpleContainer container;
public App(SimpleContainer container)
{
this.container = container;
container
.PerRequest<ShellViewModel>();
this.DisplayRootView<ShellView>();
}
protected override void PrepareViewFirst(NavigationPage navigationPage)
{
container.Instance<INavigationService>(new NavigationPageAdapter(navigationPage));
}
}
}
ShellView.xaml:
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:UniversalSqlManager"
x:Class="UniversalSqlManager.Views.ShellView"
xmlns:cm="clr-namespace:Caliburn.Micro.Xamarin.Forms;assembly=Caliburn.Micro.Platform.Xamarin.Forms"
ItemsSource="{Binding Items}"
SelectedItem="{Binding ActiveItem, Mode=TwoWay}"
Title="Universal SQL Manager">
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding DisplayName}" cm:View.Model="{Binding}" />
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
ShellView.xaml.cs:
using Xamarin.Forms;
namespace UniversalSqlManager.Views
{
public partial class ShellView
{
public ShellView()
{
InitializeComponent();
}
}
}
ShellViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using Caliburn.Micro.Xamarin.Forms;
using UniversalSqlManager.ViewModels.Interfaces;
namespace UniversalSqlManager.ViewModels
{
public class ShellViewModel : Conductor<ITabItem>.Collection.OneActive
{
protected override void OnInitialize()
{
//both view models implement ITabItem (which has no methods) and inherit form Screen
Items.Add(new ServersViewModel());
Items.Add(new SettingsViewModel());
ActivateItem(Items[0]);
}
}
}
我将展示 iOS,因为这是我测试的第一个平台
AppDelegate.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using Foundation;
using UIKit;
namespace UniversalSqlManager.iOS
{
[Register(nameof(AppDelegate))]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
private readonly CaliburnAppDelegate appDelegate = new CaliburnAppDelegate();
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(IoC.Get<App>());
return base.FinishedLaunching(app, options);
}
}
}
CaliburnAppdelegate.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Caliburn.Micro;
using UniversalSqlManager.ViewModels.Interfaces;
namespace UniversalSqlManager.iOS
{
public class CaliburnAppDelegate : CaliburnApplicationDelegate
{
private SimpleContainer container;
public CaliburnAppDelegate()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Instance(container);
container.Singleton<App>();
container.Singleton<IEventAggregator, EventAggregator>();
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
}
}
因此,当我 运行 出现此 ShellView UI 时,但 ShellViewModel 未初始化,我也没有获得任何选项卡。即使我切换到 SettingsView 或 ServersView,相应的视图模型也永远不会被初始化。我究竟做错了什么?这是我第一次在 Xamarin.Forms 上使用 Caliburn Micro。我过去使用 WPF 没有问题。只是文档令人困惑,因为看起来我们有这些示例和一些不如 WPF 文档详细的博客。任何帮助,将不胜感激。我可以 post 我的 csproj 和 project.json 如果这也有帮助,但我犹豫是否要切换项目类型,因为设置它很痛苦。我想另一种选择是创建一个带有 PCL 的新项目,看看是否可行? 运行 没主意了。感谢您的帮助!
原来问题是我没有告诉框架要使用哪些程序集。功能示例不使用共享代码库。所以我分别将其添加到 CaliburnAppDelegate.cs 和 Application.cs 到 iOS 和 Android:
protected override IEnumerable<Assembly> SelectAssemblies()
{
return this.GetAssemblies();
}
这是我在 class 库中创建的扩展:
public static class Bootstrapper
{
//...
public static IEnumerable<Assembly> GetAssemblies(this object o)
{
IEnumerable<Assembly> assemblies =
new[]
{
o.GetType().GetTypeInfo().Assembly,
typeof(ShellViewModel).GetTypeInfo().Assembly
};
return assemblies;
}
//...
}
这就解决了问题。我希望这可以帮助其他在使用 class 库连接示例时遇到问题的人。顺便说一下,我在与设置示例进行比较时发现了这一点。
我创建了一个新的 Xamarin.Forms 项目,但我在视图模型初始化方面遇到了问题。什么都没发生。我正在使用 Features 中的示例。我将示例代码修改为以下内容:
public FormsApp(SimpleContainer container)
{
//...
DisplayRootView<ConductorView>();
}
这按预期工作,但在我的项目中它根本不起作用。
我正在使用 .NET Standard 1.5(不确定这是否会导致问题)。无论如何这是我的代码
App.cs:
using System;
using Caliburn.Micro;
using Caliburn.Micro.Xamarin.Forms;
using UniversalSqlManager.ViewModels;
using Xamarin.Forms;
using INavigationService = Caliburn.Micro.Xamarin.Forms.INavigationService;
using UniversalSqlManager.Views;
namespace UniversalSqlManager
{
public class App : FormsApplication
{
private readonly SimpleContainer container;
public App(SimpleContainer container)
{
this.container = container;
container
.PerRequest<ShellViewModel>();
this.DisplayRootView<ShellView>();
}
protected override void PrepareViewFirst(NavigationPage navigationPage)
{
container.Instance<INavigationService>(new NavigationPageAdapter(navigationPage));
}
}
}
ShellView.xaml:
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:UniversalSqlManager"
x:Class="UniversalSqlManager.Views.ShellView"
xmlns:cm="clr-namespace:Caliburn.Micro.Xamarin.Forms;assembly=Caliburn.Micro.Platform.Xamarin.Forms"
ItemsSource="{Binding Items}"
SelectedItem="{Binding ActiveItem, Mode=TwoWay}"
Title="Universal SQL Manager">
<TabbedPage.ItemTemplate>
<DataTemplate>
<ContentPage Title="{Binding DisplayName}" cm:View.Model="{Binding}" />
</DataTemplate>
</TabbedPage.ItemTemplate>
</TabbedPage>
ShellView.xaml.cs:
using Xamarin.Forms;
namespace UniversalSqlManager.Views
{
public partial class ShellView
{
public ShellView()
{
InitializeComponent();
}
}
}
ShellViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using Caliburn.Micro.Xamarin.Forms;
using UniversalSqlManager.ViewModels.Interfaces;
namespace UniversalSqlManager.ViewModels
{
public class ShellViewModel : Conductor<ITabItem>.Collection.OneActive
{
protected override void OnInitialize()
{
//both view models implement ITabItem (which has no methods) and inherit form Screen
Items.Add(new ServersViewModel());
Items.Add(new SettingsViewModel());
ActivateItem(Items[0]);
}
}
}
我将展示 iOS,因为这是我测试的第一个平台
AppDelegate.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using Caliburn.Micro;
using Foundation;
using UIKit;
namespace UniversalSqlManager.iOS
{
[Register(nameof(AppDelegate))]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
private readonly CaliburnAppDelegate appDelegate = new CaliburnAppDelegate();
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(IoC.Get<App>());
return base.FinishedLaunching(app, options);
}
}
}
CaliburnAppdelegate.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Caliburn.Micro;
using UniversalSqlManager.ViewModels.Interfaces;
namespace UniversalSqlManager.iOS
{
public class CaliburnAppDelegate : CaliburnApplicationDelegate
{
private SimpleContainer container;
public CaliburnAppDelegate()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Instance(container);
container.Singleton<App>();
container.Singleton<IEventAggregator, EventAggregator>();
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
}
}
因此,当我 运行 出现此 ShellView UI 时,但 ShellViewModel 未初始化,我也没有获得任何选项卡。即使我切换到 SettingsView 或 ServersView,相应的视图模型也永远不会被初始化。我究竟做错了什么?这是我第一次在 Xamarin.Forms 上使用 Caliburn Micro。我过去使用 WPF 没有问题。只是文档令人困惑,因为看起来我们有这些示例和一些不如 WPF 文档详细的博客。任何帮助,将不胜感激。我可以 post 我的 csproj 和 project.json 如果这也有帮助,但我犹豫是否要切换项目类型,因为设置它很痛苦。我想另一种选择是创建一个带有 PCL 的新项目,看看是否可行? 运行 没主意了。感谢您的帮助!
原来问题是我没有告诉框架要使用哪些程序集。功能示例不使用共享代码库。所以我分别将其添加到 CaliburnAppDelegate.cs 和 Application.cs 到 iOS 和 Android:
protected override IEnumerable<Assembly> SelectAssemblies()
{
return this.GetAssemblies();
}
这是我在 class 库中创建的扩展:
public static class Bootstrapper
{
//...
public static IEnumerable<Assembly> GetAssemblies(this object o)
{
IEnumerable<Assembly> assemblies =
new[]
{
o.GetType().GetTypeInfo().Assembly,
typeof(ShellViewModel).GetTypeInfo().Assembly
};
return assemblies;
}
//...
}
这就解决了问题。我希望这可以帮助其他在使用 class 库连接示例时遇到问题的人。顺便说一下,我在与设置示例进行比较时发现了这一点。