多くの場合、イメージはプラットフォーム固有です。デバイス自体のサイズとDPIに対応する必要があり、アプリケーションのルックアンドフィールに適合させる必要があります。このような状況では、おそらくViewModelによって提供されるある種の状態/モードに基づいて、View自体にユーザーに表示する画像を決定させます。
ただし、これらは、たとえばメールアプリケーションに表示される送信者のサムネイルの場合など、画像をViewModelから取得する必要がある場合です。このような場合、ViewModelにプラットフォームに依存しない画像の概念(byte []など)を返してもらい、プラットフォーム固有のプロジェクトでそれをUIスタックが理解できるものに変換します(XAMLでは、 ImageSourceになります)。
コードは次のようになります。
ポータブルプロジェクト:
using System.IO;
using System.Reflection;
namespace Portable
{
public class ViewModel
{
private byte[] _image = LoadFromResource("Image.png");
public byte[] Image
{
get { return _image; }
}
private static byte[] LoadFromResource(string name)
{
using (Stream stream = typeof(ViewModel).GetTypeInfo().Assembly.GetManifestResourceStream("Portable." + name))
{
MemoryStream buffer = new MemoryStream();
stream.CopyTo(buffer);
return buffer.ToArray();
}
}
}
}
注:ターゲットとするプラットフォームに応じて、GetTypeInfo()を削除または追加する必要があります。
ここでは、埋め込みリソース([プロパティ]->[ビルドアクション]->[埋め込みリソース])から読み取っていますが、これはネットワークまたは他の場所からのものであると想像できます。
Windowsストアアプリプロジェクト:
Windowsストアアプリでは、byte []-> ImageSourceから変換する値コンバーターがあります:
using System;
using System.IO;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media.Imaging;
namespace App
{
public class ByteToImageSourceValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
InMemoryRandomAccessStream s = new InMemoryRandomAccessStream();
byte[] bytes = (byte[])value;
Stream stream = s.AsStreamForWrite();
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
BitmapImage source = new BitmapImage();
source.SetSource(s);
return source;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
ビューの背後にあるコードで、DataContextを設定します。
DataContext = new ViewModel();
次に、View自体でViewModel.Imageプロパティにバインドし、コンバーターを設定します。
<Page.Resources>
<local:ByteToImageSourceValueConverter x:Name="ImageConverter"/>
</Page.Resources>
<Grid >
<Image HorizontalAlignment="Left" Height="242" Margin="77,10,0,0" VerticalAlignment="Top" Width="278" Source="{Binding Image, Converter={StaticResource ImageConverter}}"/>
</Grid>