在没有应用程序对象模式下的Caliburn micro,就像在AutoCAD dll插件中一样 [英] Caliburn micro in no Application object mode, like in AutoCAD dll plugin

查看:123
本文介绍了在没有应用程序对象模式下的Caliburn micro,就像在AutoCAD dll插件中一样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Caliburn Micro开发WPF应用程序.该应用程序的一些视图需要在AutoCAD环境中加载. AutoCAD编程环境允许开发AutoCAD插件(dll类型)并将其加载到AutoCAD环境中.

I am using Caliburn Micro to develop WPF application. A few of views of this application needs to be loaded in an AutoCAD environment. The AutoCAD programming environment allows developement of AutoCAD plugins (of type dll) and load them into the AutoCAD environment.

由于AutoCAD插件类型(dll),该插件没有应用程序对象,因此必须为此自定义引导程序.根据Caliburn Micro文档此处(向下滚动到使用Caliburn. Office和WinForms应用程序中的Micro"),我们可以继承非通用引导程序,并将"false"传递给基本构造函数的"useApplication"参数.因此,我继续创建了定制的引导程序.

Because of AutoCAD plugin type(dll), the plugin does not have an Application Object, so the bootstrapper has to be customized for that. According to the Caliburn Micro documentation here (Scroll down to "Using Caliburn.Micro in Office and WinForms Applications") we can inherit the non-generic bootstrapper and pass "false" to the base constructor's "useApplication" parameter. So, I went ahead and created the customized bootstrapper.

问题在于,ConfigureContainer()重写永远不会被调用,也不会初始化任何内容.另外,我不确定如何使用ViewModel first概念加载ShellView.这是我到目前为止提出的一些代码.

The issue is that the ConfigureContainer() override never gets called and nothing gets initialized. Also, I am not sure how to load the ShellView using ViewModel first concept. Here is some code that I have come up till now.

自举程序

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窗体的load事件中,我创建了一个实例化caliburn micro bootstrapper的实例,并期望引导程序做所有的事情并加载Shell.但是Shell无法加载.我在AutoCAD中显示了空白窗口.这是Windows窗体的编码方式.

I have a windows form which the AutoCAD loads when requested. In the Windows Form's loaded event, I create an instance cuztomized caliburn micro bootstrapper and expect the boot strapper to do all the magic and load the Shell. But the Shell does not load. I get the blank window displayed in the AutoCAD. Here is how the Windows Form is coded.

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.由于无法加载ShellView,因此无法配置Caliburn Micro.

So in summary, I am trying use Caliburn Micro in an hosted environment which is not loaded using the Application object. I am unable to configure Caliburn Micro, as the ShellView never loads.

推荐答案

此问题已解决.问题是在AutoCAD本身中加载支持程序集(dll)会产生错误.请参阅线程.正确加载程序集后,我可以使用Caliburn Micro,它也可以在非WPF环境中使用.

This issue has been resolved. The problem was that loading of supporting assemblies (dll's) in AutoCAD itself was giving error. Please See this thread. Once the assemblies were loaded correctly, I could use the Caliburn Micro and it works in non-WPF environment too.

我将在逻辑上显示该过程.我在纯wpf应用程序中开发的wpf屏幕将在AutoCAD插件中重复使用,但是由于autocad插件是类library(dll),因此没有Application对象可用.启动AutoCAD后,将在我可以初始化caliburn微型引导程序的位置执行插件代码.这是相关的插件代码.

I will logically show the process. The wpf screen that I had developed in a pure wpf application was to be re-used in AutoCAD plugin, but since autocad plugin's are class library(dll), there is no Application object available. When AutoCAD is launched, the plugin code executes where I could initialize the caliburn micro bootstrapper. Here is the relevant plugin code.

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();
    }

请注意,应用程序的关闭模式为显式".这是必需的,尽管我不记得为什么!

Note that the Application has a shutdown mode of Explicit. This is required, although I don't remember why!

Bootstrapper的区别不大,只是我们按照文档中所述将false传递给基本构造函数.这就是引导程序的样子

There is not much difference in the Bootstrapper, except that we pass false to the base constructor as mentioned in documentation. Here is what the Bootstrapper looks like

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有点相关,但是为了完整起见,我将与您分享.

This is the configuration part which happens only once when the plugin is loaded the calibur micro is configured. After this the code is a bit related to AutoCAD but for the sake of completeness, I will share.

QueryRelay.cs 此类接受AutoCAD用户的命令输入,然后显示请求的视图

QueryRelay.cs This class accepts command input from AutoCAD user and then displays the requested 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的代码

Since the windows in AutoCAD are shown using the AutoCAD's API, I had to customize the Caliburn Micro WindowManager slightly. Here is the code for the 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).

I ask the CaliburnMicro to create View from ViewModel(rootModel in above code), which then is loaded in AutoCAD using the AutoCAD API. How the View is shown will depend on the hosting application (AutoCAD in my case).

最后,必须在BootStrapper配置中注册CustomWindowManager

Finally the CustomWindowManager has to be registered in the BootStrapper Configure

    protected override void Configure() {
        ...
        var batch = new CompositionBatch();
        batch.AddExportedValue<IWindowManager>(new CustomWindowManager());
        container.Compose(batch);
        ...
    }

致谢, 尼尔万(Nirvan)

regards, Nirvan

这篇关于在没有应用程序对象模式下的Caliburn micro,就像在AutoCAD dll插件中一样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆