クラスライブラリ(DLL)にウィンドウを追加できない
Visual Studio Community 2017(Version 15.9.4)で、クラスライブラリ(.NET Framework DLL)の中に WPF のウィンドウを追加しようとしたんだけど。。。
あれっ!? [新しい項目の追加]ダイアログの WPF のところにウィンドウが見当たりませんヨ~!?
下図のような状態を想定していたんですが。(下図は別のアプリケーションプロジェクトの画面)
最初は「Visual Studio のバグかな!?」「プロジェクトファイルのどこかに問題が発生したかな!?」と思って調べまわったんですが、そうではないようでした。
アプリケーションのプロジェクトと違って、そもそも、クラスライブラリのプロジェクトに WPF のウィンドウを追加するオプションは無いということのようです。
「え~~~なんで~~~??」
でも、でも、理由は分からないけれど、私が過去に作ったクラスライブラリのプロジェクトには WPF のウィンドウが追加されていますヨ。はて? どうやって追加したんだっけ? 記憶が無い・・・。
それで、クラスライブラリにウィンドウを追加する方法が無いか調べてみたところ、3種類ほどのやり方を見つけました。
方法1:Visual Studio の UI から新規追加できるようにする
たぶんこの方法が1番スマートな方法だと思いますが、Visual Studio のバージョン(仕様の違い)によってはうまくいかないことがあるかもしれません。
プロジェクトファイルの編集
まず、クラスライブラリのプロジェクトを開いている場合は、閉じてください。
次にクラスライブラリのプロジェクトファイル .vbproj をテキストエディタで開いて、<PropertyGroup> ~ </PropertyGroup> の間に下記の1行を挿入します。
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
下図は .vbproj ファイルに上の行を挿入したときのスクリーンショット。
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548} が WPF の Project Type GUID を表し、{F184B08F-C81C-45F6-A57F-5ABD9991F28F} が VB.NET の Project Type GUID です。
ちなみに C# プロジェクトの場合は .csproj を編集して、VB.NET の GUID を C# の GUID である {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} で置き換えてください。
VB.NET と C# の GUID を間違えて指定すると、プロジェクトを開くときと開いた後で下記のようなエラーが発生します。
プロジェクトファイルの編集が終わったら、保存して閉じてください。
参照の追加
次に、クラスライブラリのプロジェクトを開いて、下記の4つの参照を追加します。
- PresentationCore
- PresentationFramework
- System.Xaml
- WindowsBase
下図は PresentationCore と PresentationFramework の参照を追加しているところ。
下図は参照の追加が終わった様子を示しています。
以上で設定は終わりです。
Visual Studio の UI から WPF ウィンドウを新規追加する
ではクラスライブラリに新規ウィンドウを追加してみましょう。
ソリューションエクスプローラーでクラスライブラリプロジェクトを右クリックして[追加]を選択すると、以前には表示されなかった[ウィンドウ]メニューがあるのが分かります。が、ここでは[新しい項目]のほうを選択してみましょう。
[新しい項目の追加]ダイアログの WPF のところからウィンドウを追加できるようになりました。
追加した WPF ウィンドウの動作テスト
クラスライブラリに追加した WPF ウィンドウが正常に動作するかテストしてみました。
まずクラスライブラリをビルドして DLL を生成しておきます。
次に、アプリケーションプロジェクトの参照にクラスライブラリへの参照を追加します。
アプリケーションの Loaded イベントに、クラスライブラリのウィンドウを呼び出すコードを書きました。これでアプリケーションを起動、と。
ちゃんとクラスライブラリのウィンドウが表示されました。動作テスト OK です。
方法2:アプリケーションプロジェクトのウィンドウを流用する
他のアプリケーションプロジェクトで作成した WPF ウィンドウのファイルを流用する方法です。
アプリケーションプロジェクトの WPF ウィンドウをコピペする
新規または既存のアプリケーションプロジェクトで WPF ウィンドウを作成したら、そのファイル(.xaml と .xaml.vb)をコピーします。
コピーしたファイルをクラスライブラリのフォルダ内にペーストします。
WPF ウィンドウのルート名前空間を修正する
クラスライブラリのプロジェクトファイル(.vbproj)と、ペーストした WPF ウィンドウの .xaml をテキストエディタで開きます。
そして、xaml の clr-namespace:xxxxx の xxxxx のところに、プロジェクトファイルの <RootNamespace> ~ </RootNamespace> で挟まれているルート名前空間を上書きします。
下図は上書き後の様子です。
WPF ウィンドウのルート名前空間の修正は Visual Studio の中から行うこともできます。
クラスライブラリのルート名前空間は、Visual Studio でクラスライブラリのプロジェクトを開いた後、プロジェクトのプロパティから調べることもできます。
参照の追加
次に、クラスライブラリのプロジェクトを開いて、下記の4つの参照を追加します。
- PresentationCore
- PresentationFramework
- System.Xaml
- WindowsBase
下図は PresentationCore と PresentationFramework の参照を追加しているところ。
下図は参照の追加が終わった様子を示しています。
既存の WPF ウィンドウの追加
アプリケーションプロジェクトからコピペしてきた WPF ウィンドウをクラスライブラリのプロジェクトに追加します。
ソリューションエクスプローラーで、クラスライブラリのプロジェクトを右クリックし、[追加]>[既存の項目]を選択。
[既存項目の追加]ダイアログで、ファイルの種類を XAML ファイルに変更します(下図の赤枠のところ)。
ファイルの種類を変更したら、追加する WPF ウィンドウの .xaml ファイルを選択して、[追加]ボタンをクリックします。
私の環境では、ウィンドウを追加した直後、下図のようにちょっと変な表示状態になりました(左端にあるべき三角記号 ▷ がありません)。
これはちょっとした表示上のバグのようです。動作に影響は無いようでした。
また、プロジェクトを閉じてから開き直すと、下図のように正常な表示になりました。
追加した WPF ウィンドウの動作テスト
この記事の「方法1」と同様の動作テストをし、正常に動作することを確認しました。
方法3:アプリケーションプロジェクトをクラスライブラリプロジェクトに変換する
アプリケーションプロジェクトで WPF ウィンドウを作成してから、プロジェクトをまるごとクラスライブラリに変換するやり方もあるようです(プロジェクトのプロパティの[アプリケーションの種類]を[クラスライブラリ]に変更する)。