我正在使用Caliburn Micro来开发WPF应用程序。需要在AutoCAD环境中加载此应用程序的一些视图。 AutoCAD编程环境允许开发AutoCAD插件(类型为dll)并将其加载到AutoCAD环境中。
由于AutoCAD插件类型(dll),插件没有应用程序对象,因此必须为其自定义引导程序。根据Caliburn Micro文档here (Scroll down to "Using Caliburn.Micro in Office and WinForms Applications"),我们可以继承非通用引导程序并将“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;
}
}
我有一个窗口表单,AutoCAD会在请求时加载。在Windows窗体的加载事件中,我创建了一个实例cuztomized caliburn微引导程序,并期望引导过滤器完成所有魔法并加载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();
}
}
总而言之,我正在尝试在未使用Application对象加载的托管环境中使用Caliburn Micro。我无法配置Caliburn Micro,因为ShellView永远不会加载。
答案 0 :(得分:4)
此问题已得到解决。问题是在AutoCAD中装载支撑组件(dll)本身就给出了错误。请参阅this主题。正确加载程序集后,我可以使用Caliburn Micro,它也适用于非WPF环境。
修改强> 我将在逻辑上显示该过程。我在纯wpf应用程序中开发的wpf屏幕将在AutoCAD插件中重复使用,但由于autocad插件是类库(dll),因此没有可用的Application对象。启动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();
}
请注意,Application的关闭模式为Explicit。这是必需的,虽然我不记得为什么!
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有点相关,但为了完整起见,我将分享。
<强> QueryRelay.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。这是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创建View(上面代码中的rootModel),然后使用AutoCAD API将其加载到AutoCAD中。显示视图的方式取决于托管应用程序(在我的情况下为AutoCAD)。
最后,必须在BootStrapper配置
中注册CustomWindowManager protected override void Configure() {
...
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new CustomWindowManager());
container.Compose(batch);
...
}
的问候, NIRVAN