Caliburn.Microのワークフロー

今時デスクトップアプリをWPFで作るのかい!ってところですが、今で作るんです。ちょっと前までFormで作ってましたが、さすがに150%がどうしたとかイヤになってきたので、WPFにしました。で、せっかくなんでMVVMでやろうよ、ということで始めたのがCaliburnです(Prismじゃねーの)。

ゼロからやるときの手順を忘れがちなので、お作法をまとめ。

プロジェクト作成

WPFアプリ(.NET Framework)です。そして真っ先にMainWindow.xamlを削除します。

nuget

Caliburn.Microをnuget。4.0.212から進みませんね。大体ここでリポジトリを始めたりします。

App.xamlを修正

<Application x:Class="CaliburnSample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:CaliburnSample"
             >
    <Application.Resources>
        <!-- Caliburn.Micro -->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:SimpleBootstrapper x:Key="Bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Bootstrapperの名前をSimpleBootstrapperにしています。

ここでStartupUriを消すのをよく忘れるので注意。

SimpleBootstrapper.csをプロジェクトのルートフォルダに作成

    public class SimpleBootstrapper : BootstrapperBase
    {
        private SimpleContainer container;

        public SimpleBootstrapper()
        {
            Initialize();
            LogManager.GetLog = type => new DebugLog(type);
        }

        protected override void Configure()
        {
            container = new SimpleContainer();

            container.Singleton<IWindowManager, WindowManager>();
            container.Singleton<IEventAggregator, EventAggregator>();

            container.PerRequest<ShellViewModel>();
            container.PerRequest<MainViewModel>();
        }

        protected override object GetInstance(Type service, string key)
        {
            return container.GetInstance(service, key);
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return container.GetAllInstances(service);
        }

        protected override void BuildUp(object instance)
        {
            container.BuildUp(instance);
        }

        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewForAsync<ShellViewModel>();
        }

        protected override IEnumerable<Assembly> SelectAssemblies()
        {
            return new[] { Assembly.GetExecutingAssembly() };
        }
    }

この辺はもうコピペ。とりあえずはエラーでまくりですが、気にしない。

フォルダModels,ViewModels,Viewsを作成

Caliburnでは名前は重要。MVVMっぽくフォルダを作ります。

ViewModels\ShellViewModel.csを作成

    public class ShellViewModel : Conductor<object>
    {
        protected async override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
            await ActivateItemAsync(IoC.Get<MainViewModel>(), new CancellationToken());
        }
    }

Views\ShellView.xamlを作成

「追加」-> 「ウインドウ(WPF)」で作ること。

    <Grid>
        <ContentControl x:Name="ActiveItem"/>
    </Grid>

ViewModels\MainViewModel.csを作成

	public class MainViewModel : Screen
	{
	}

ほんとは何もしなくていいんですが、今後のためにやっておく。

Views\MainViewModel.xamlを作成

「追加」-> 「ユーザーコントロール(WPF)」で作ること。

    <Grid>
        <Label Content="This is main view."/>
    </Grid>

SimpleBootstrapper.csのエラー修正

usingが足りないのでエラーが出てるのを修正。

ビルドしてデバッグ

ちゃんとできていれば、This is main view.と表示される。いやー、Caliburn好き。Xaml全然わかんね。