Neutral Scent

App developments & Gadgets

XAMLのアセンブリ参照をVSデザイナに認識させるトリック

過去のエントリでも少し触れていますが、UserControlやデータバインドのIValueConverterなどを使いたい時、XAMLにそのまま記述するとVisual StudioのデザイナやExpressionがWhoopsなどを表示してうまく編集できなくなることがあります。
デザイナがなくてもやってやれないことは無いのですが、画面レイアウトやデザインの調整などが非常にやっかいで勘弁して欲しい状況になります。
あちこち見てみた感じだとVSのbugで次のCTPで直るよ、ってことらしいんですが、ずいぶん前からこんなだよな、と...。
ようするに、

xmlns:fb="clr-namespace:FooBar;assembly=FooBar"

が、

Assembly 'FooBar' was not found. The 'clr-namespace' URI refers to an assembly that is not referenced by the project.

なんてエラーを吐いてたりしたときの対策です。
対策方法としては、参照したいカスタムコントロールなどをDLLに追い出します。
ただし、デザイナに認識させるには、そのときに妙なトリックを使います。

  1. ソリューションに新しいプロジェクトを追加します。
    ワタシは「Custom Control Libraey (WPF)」を使いましたが、「ふつうのクラスライブラリ」でもいいんじゃないかな...? 既存のクラスライブラリがあればそれを使えばよいです。
  2. カスタムコントロールなどをそちらのプロジェクトに追加・実装します。
  3. カスタムコントロールのプロジェクトをビルドしてDLLを生成します。
  4. 参照側のアプリケーションで、クラスライブラリへの参照を追加します。
    ここがポイント:
    通常クラスライブラリのプロジェクトを参照に追加する場合、プロジェクトの参照の追加ダイアログから「プロジェクト」タブで同一ソリューション内のクラスライブラリのプロジェクトを追加するのが美しい(?)わけですが、これではダメです(後述)。
    ここでは、「参照」タブで直接、3.で生成されているクラスライブラリのDLLをファイルで指定します

きわめて偶然に、3DToolsを使ってみよう、と、川西 裕幸さんの書かれたサンプルコードを実行したりしてる時に気づいたんです。「なんでこのコード、参照してるのにちゃんとデザイナが使えるの!? 3DToolsのオフィシャルサンプルでは使えないのに!」みたいな。
色々トライして、↑の形態にたどり着きました。
なんでやねん? と思って、OKとNGで.csprojの差分をとってみたんですが、

OK:
  
    False
    ..\FooBar\bin\Debug\FooBar.dll
  
NG:
  
    
      {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
      FooBar
    
  

という感じで参照方法が違うみたいですね。さらにコンパイラへの渡し方とか研究するともっといい方法があるかも知れません。
まー、次のCTPまでのごまかしということで、こんな方法もあるよ、という小技でした。