此问题已得到解决。问题是在 AutoCAD 本身中加载支持程序集 (dll) 时出现错误。请参见this https://stackoverflow.com/questions/13660652/targetting-x64-platform-with-entity-framework-4-1-in-visual-studio-2010#comment18749389_13660652线。正确加载程序集后,我就可以使用 Caliburn Micro,它也可以在非 WPF 环境中工作。
Edit:我将逻辑地展示这个过程。我在纯wpf应用程序中开发的wpf屏幕将在AutoCAD插件中重用,但由于autocad插件是类库(dll),因此没有可用的Application对象。当 AutoCAD 启动时,插件代码将在我可以初始化 calibburn 微引导程序的位置执行。这是相关的插件代码。
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();
}
请注意,应用程序的关闭模式为显式。这是必需的,虽然我不记得为什么!
Bootstrapper 中没有太大区别,只是我们将 false 传递给文档中提到的基本构造函数。这是 Bootstrapper 的样子
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 有点相关,但为了完整起见,我将共享。
查询中继.cs此类接受来自 AutoCAD 用户的命令输入,然后显示请求的视图
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。这是自定义WindowManager的代码
自定义WindowManager.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)。
最后,必须在 BootStrapper 配置中注册 CustomWindowManager
protected override void Configure() {
...
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new CustomWindowManager());
container.Compose(batch);
...
}
问候,
涅槃