我正在使用Caliburn Micro开发WPF应用程序。此应用程序的一些视图需要在AutoCAD环境中加载。AutoCAD编程环境允许开发AutoCAD插件(dll类型)并将其加载到AutoCAD环境中。
由于AutoCAD插件类型(dll)的原因,该插件没有应用程序对象,因此必须为此自定义引导程序。根据此处的Caliburn-Micro文档(向下滚动至"在Office和WinForms应用程序中使用Caliburn.Micro"),我们可以继承非通用引导程序,并将"false"传递给基本构造函数的"useApplication"参数。所以,我继续创建了定制的引导程序。
问题是永远不会调用ConfigureContainer()重写,也不会初始化任何内容。此外,我不知道如何使用ViewModel第一个概念加载ShellView。这是我到目前为止提出的一些代码。
引导程序
public class AutocadMefBootStrapper : Bootstrapper {
private CompositionContainer container;
private ElementHost host;
public AutocadMefBootStrapper(ElementHost host) : base(false) {
this.host = host;
}
protected override void Configure() { //Not getting invoked.
...
var rootViewModel = container.GetExportedValue<IShell>();
var rootView = ViewLocator.LocateForModel(rootViewModel, null, null);
host.Child = rootView;
}
}
我有一个windows窗体,AutoCAD会在需要时加载它。在Windows窗体的loaded事件中,我创建了一个实例cuztomized caliburn micro引导程序,并期望引导程序完成所有的魔术并加载Shell。但是Shell不加载。我在AutoCAD中显示了空白窗口。以下是Windows窗体的编码方式。
public partial class WinFormHost : Form {
private void WinFormHost_Load(object sender, EventArgs e) {
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
Controls.Add(host);
AutocadMefBootStrapper bootStrapper = new AutocadMefBootStrapper(host);
}
}
这是我的ShellView
<UserControl x:Class="RelayAnalysis_Autocad.Views.ShellView"
...
<Grid>
<TextBlock>Hello There</TextBlock>
</Grid>
</UserControl>
和ShellViewModel
[Export(typeof(IShell))]
public class ShellViewModel : Conductor<object>, IShell {
protected override void OnActivate() {
base.OnActivate();
}
}
总之,我正在尝试在托管环境中使用Caliburn Micro,该环境不是使用Application对象加载的。我无法配置Caliburn Micro,因为ShellView从未加载。
此问题已得到解决。问题是在AutoCAD中加载支持程序集(dll)本身会出错。请看这个帖子。一旦组件正确加载,我就可以使用Caliburn Micro,它也可以在非WPF环境中工作。
编辑:我将按逻辑显示流程。我在纯wpf应用程序中开发的wpf屏幕将在AutoCAD插件中重新使用,但由于AutoCAD插件是类库(dll),因此没有可用的应用程序对象。当AutoCAD启动时,插件代码会在我可以初始化caliburn微型引导程序的地方执行。以下是相关的插件代码。
MyPlugin.cs
public class MyPlugin : IExtensionApplication {
//Called when plugin is loaded. This is where I load xaml resources, since there is no App.xaml available
void IExtensionApplication.Initialize() {
if (System.Windows.Application.Current == null) {
new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
}
System.Windows.Application.Current.Resources.MergedDictionaries.Add(System.Windows.Application.LoadComponent(
new Uri("RelayAnalysis_Autocad;component/Content/Styles/CommonBrushes.xaml", UriKind.Relative)) as ResourceDictionary);
System.Windows.Application.Current.Resources.MergedDictionaries.Add(System.Windows.Application.LoadComponent(
new Uri("RelayAnalysis_Autocad;component/Content/Styles/Button.xaml", UriKind.Relative)) as ResourceDictionary);
...
//Load Other xaml resources
...
//Initialize the Bootstrapper
AutocadMefBootStrapper bootstrapper = new AutocadMefBootStrapper();
}
//Called when plugin is unloaded
void IExtensionApplication.Terminate() {
// Do plug-in clean up here
System.Windows.Application.Current.Shutdown();
}
请注意,应用程序的关闭模式为Explicit。这是必须的,尽管我不记得为什么了!
Bootstrapper没有太大区别,只是我们将false传递给了文档中提到的基本构造函数。以下是引导程序的外观
AutocadMefBootStrapper.cs
public class AutocadMefBootStrapper : Bootstrapper {
public static CompositionContainer container;
public AutocadMefBootStrapper()
: base(false) {
}
protected override void Configure() {
//Create and Add Catalogs.
AssemblyCatalog currentAssemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
AssemblyCatalog domainAssemblyCatalog =
new AssemblyCatalog(Assembly.GetAssembly(typeof(RelayAnalysis_Domain.Entity.Rack)));
...
}
这是配置部分,当加载插件并配置calibur micro时,只会发生一次。在此之后,代码与AutoCAD有点相关,但为了完整起见,我将与大家分享。
QueryRelay.cs此类接受AutoCAD用户的命令输入,然后显示请求的View
public class QueryRelay {
//This command is used to display a particular View. This is entered from AutoCAD Command Window
public void QueryRelayCommand() {
//Get the ViewModel for the screen from Container
AcadRelayListViewModel relayListViewModel = AutocadMefBootStrapper.container.GetExportedValue<AcadRelayListViewModel>();
IWindowManager windowManager = AutocadMefBootStrapper.container.GetExportedValue<IWindowManager>();
windowManager.ShowWindow(relayListViewModel);
...
}
}
由于AutoCAD中的窗口是使用AutoCAD的API显示的,因此我不得不稍微自定义Caliburn Micro WindowManager。这是CustomWindowManager 的代码
CustomWindowManager.cs
public class CustomWindowManager : WindowManager {
public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null) {
Autodesk.AutoCAD.ApplicationServices.Application.ShowModalWindow(null, CreateWindow(rootModel, false, null, null), false);
}
}
我要求CaliburnMicro从ViewModel创建视图(上面代码中的rootModel),然后使用AutoCAD API将其加载到AutoCAD中。视图的显示方式将取决于宿主应用程序(在我的情况下是AutoCAD)。
最后,必须在引导程序配置中注册CustomWindowManager
protected override void Configure() {
...
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new CustomWindowManager());
container.Compose(batch);
...
}
问候,Nirvan