2011年11月25日金曜日

wpf : UserControlを含んだクラスライブラリ(dll)の作成とデバッグ

wpfでUserControlを含んだクラスライブラリを作ったときのメモです。 最初は空プロジェクトにUserControlを追加してやってみたんですが、そのままではデバッグできませんでした。 デバッグ用に別プロジェクトでウィンドウを作って、そこでAssembly.LoadFrom → UserControlを貼り付けでデバッグしようとしたらUserControl内のコードでステップ実行ができませんでした。 困りますよね?

少々試行錯誤したところ、MainWindow付きの「wpfアプリケーション」でプロジェクトを作って、後で出力をクラスライブラリに変更する方法を発見。 作成&デバッグはMainWindowに貼り付けてやって、リリース時にdllを作る方法がわかりました。 これでUserControlのデバッグができます。 未確認ですが、カスタムコントロールとかを作るときにも同じようにできそうです。

出力の「実行ファイル」⇔「クラスライブラリ」の変更方法は、

  • プロジェクトのプロパティでアプリケーションの出力の種類を「windowsアプリケーション」⇔「クラスライブラリ」に変更。
  • App.xamlのプロパティで詳細/ビルドアクションを「ApplicationDefinition」⇔「なし」に変更。
  • App.xaml.csのプロパティで詳細/ビルドアクションを「コンパイル」⇔「なし」に変更。
  • MainWindow.xamlのプロパティで詳細/ビルドアクションを「Page」⇔「なし」に変更。
  • MainWindow.xaml.csのプロパティで詳細/ビルドアクションを「コンパイル」⇔「なし」に変更。

出力の種類をクラスライブラリに変えただけでは「ライブラリプロジェクトファイルは、ApplicationDefinition要素を指定できません。」と怒られてしまいます。 ApplicationDefinitionが設定されているApp.xamlをビルド対象から外せば、これは解決。 同様に、デバッグでしか使わない項目が他にあるなら、それもビルド対象から外しましょう。

このやり方が正規のやり方なのかは未確認です。 ビルド対象から外すべきものが他にあって、挙げ切れてないかもしれません。 また、debug⇔releaseなどの構成を切り替えるときのようにワンタッチで切り替えれないのも面倒だったり。

何度も「実行ファイル」⇔「クラスライブラリ」の変更を繰り返す場合、出力の種類とApp.xamlのビルドアクションだけ変更するといいかも。 クラスライブラリに余計なモノが含まれてしまうけど、設定の変更は少なくて済みます。

--------

2012年4月29日 追記)

コピー&ペーストでコーディングしてたら名前空間にアセンブリ名を書き忘れてちょいハマったので追記。 xaml上でdll内のコントロールを使うときはアセンブリ名を書かないと怒られます。

例えばこんな感じ。

<Window x:Class="使う側のプロジェクトの名前空間.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:dll内の名前空間;assembly=dllのアセンブリ名"
        Title="MainWindow" Height="???" Width="???">
    <app:UserControlとか>test</app:UserControlとか>
</Window>

clr-namespaceのところです。

Visual Studioでコーディングしていたらオートコレクトが名前空間を全部補完してくれます。 オートコレクトに任せるのが正解。 オートコレクトで出てくる候補は大量ですが、参照設定できちんとdllが追加されていればどこかにあるから探しましょう。 何かのキッカケでオートコレクト自体が効かなくなることも良くあります。 そのときはエラー部分をコメントアウトしてからいったんビルド → もう1度入力するとオートコレクトが復活するはずです。