はじめに
本記事は他プロジェクトで利用されるWPFコントロールでプロジェクトのルートを起点としたパスを利用する際に困ったので、その方法をまとめることを目的としています。
困りごと
例えば、以下のようにSampleIcon.jpgとそれを表示するMainWindow.xamlがあるとします。
このMainWindow.xamlで以下のようにImageのSourceを参照します。
<Window x:Class="AbsolutePathResolveSample.Views.MainWindow">
<Grid>
<Image Source="/Resources/Icons/SampleIcon.jpg"/>
</Grid>
</Window>
そして、AbsolutePathResolveSampleプロジェクトをスタートアッププロジェクトに設定してアプリケーションを実行すると画像が表示されます。これは上のxamlのImageコントロールのSourceに指定している/Resources/Icons/SampleIcon.jpg
が/
から始まっており、プロジェクトのルートを起点にパスを解決するためです。
では、別プロジェクトから利用されるライブラリ内でも上記と同じようなパス解決ができるのかを見てみます。
具体的には以下のようなソリューション構成を考えます。
SampleControlsプロジェクトのSampleControl.xamlは以下のように書かれており、内容は前述したMainWindow.xamlと同じです。
<UserControl x:Class="SampleControls.Views.SampleControl">
<Grid>
<Image Source="/Resources/Icons/SampleIcon.jpg"/>
</Grid>
</UserControl>
そして、SampleApplicationプロジェクトのMainWindow.xamlでは、以下のように上記のSampleControlを配置しています。
<Window x:Class="SampleApplication.MainWindow"
xmlns:Controls="clr-namespace:SampleControls.Views;assembly=SampleControls">
<Grid>
<Controls:SampleControl/>
</Grid>
</Window>
この状態でSmapleApplicationプロジェクトをスタートアッププロジェクトに設定してアプリケーションを実行すると、AbsolutePathResolveSampleプロジェクトと同じようにImageコントロールのSourceに設定したパスが解決されると思いきや、解決されず画像は表示されません。
このように別プロジェクトから利用するWPFコントロールにおいて、プロジェクトのルートを起点としたパス(つまりは/
から始まるパス)は、工夫しないと解決できません。
解決法
ImageコントロールのSourceに設定するパスの先頭に/(アセンブリ名);component
を加えることで、別プロジェクトから利用する場合であっても、パスを解決する際に起点とするアセンブリが特定されるので、パス解決できるようになります。前章のSampleControlsプロジェクトのSampleControl.xamlの場合は、アセンブリ名はプロジェクト名と同じSampleControls
なので、以下のように書けばパス解決できるようになります。
<UserControl x:Class="SampleControls.Views.SampleControl">
<Grid>
<Image Source="/SampleControls;component/Resources/Icons/SampleIcon.jpg"/>
</Grid>
</UserControl>
まとめ
本記事では他プロジェクトで利用されるWPFコントロールのxaml内でプロジェクトのルートを起点としたパス参照をする方法についてまとめました。