3

Caliburn Micro を使用して WPF アプリケーションを開発しています。このアプリケーションのいくつかのビューは、AutoCAD 環境にロードする必要があります。AutoCAD プログラミング環境では、(タイプ dll の) AutoCAD プラグインを開発し、それらを AutoCAD 環境にロードできます。

AutoCAD プラグイン タイプ (dll) のため、プラグインにはアプリケーション オブジェクトがありません。そのため、ブートストラップをカスタマイズする必要があります。Caliburn Micro のドキュメント(「Office および WinForms アプリケーションでの Caliburn.Micro の使用」まで下にスクロール)によると、非汎用ブートストラップを継承し、基本コンストラクターの「useApplication」パラメーターに「false」を渡すことができます。そこで、カスタマイズしたブートストラッパーを作成しました。

問題は、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 フォームがあります。Windows フォームのロード イベントで、カスタム化された caliburn マイクロ ブートストラップのインスタンスを作成し、ブート ストラップがすべての魔法を実行してシェルをロードすることを期待します。しかし、シェルはロードされません。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 を使用しようとしています。ShellView がロードされないため、Caliburn Micro を構成できません。

4

1 に答える 1

4

この問題は解決されました。問題は、AutoCAD自体にサポートアセンブリ(dll)をロードするとエラーが発生することでした。このスレッドをご覧ください。アセンブリが正しく読み込まれると、Caliburn Microを使用できるようになり、非WPF環境でも機能します。

編集: 私は論理的にプロセスを示します。純粋なwpfアプリケーションで開発したwpf画面は、AutoCADプラグインで再利用される予定でしたが、autocadプラグインはクラスlibrary(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であることに注意してください。理由は覚えていませんが、これは必須です。

ドキュメントに記載されているように、ベースコンストラクターにfalseを渡すことを除いて、Bootstrapperに大きな違いはありません。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)));
    ...
    }

これは、プラグインがロードされたときに1回だけ発生する構成部分であり、caliburmicroが構成されます。この後、コードは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を使用して表示されるため、CaliburnMicroWindowManagerを少しカスタマイズする必要がありました。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)からビューを作成するように依頼します。これは、AutoCADAPIを使用してAutoCADに読み込まれます。ビューがどのように表示されるかは、ホスティングアプリケーション(私の場合はAutoCAD)によって異なります。

最後に、CustomWindowManagerをBootStrapperConfigureに登録する必要があります

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

よろしく、ニルヴァン

于 2012-12-03T12:31:50.003 に答える