2008-08-21 85 views
57

バインディング:画像UriSourceとデータが私はこのようなWPFイメージにカスタムオブジェクトのリストをバインドしようとしている

<Image> 
    <Image.Source> 
     <BitmapImage UriSource="{Binding Path=ImagePath}" /> 
    </Image.Source> 
</Image> 

しかし、それは動作しません。これは私が得るエラーです:

"プロパティ 'UriSource'またはプロパティ 'StreamSource'を設定する必要があります。

何が欠けていますか?

答えて

74

WPFには、特定の種類のコンバータが組み込まれています。イメージのSourceプロパティをstringまたはUriの値にバインドすると、フードの下でWPFはImageSourceConverterを使用して値をImageSourceに変換します。

ので

<Image Source="{Binding ImageSource}"/> 

ImageSourceはプロパティは、画像への有効なURIの文字列表現した場合に動作します。

あなたはもちろん、独自のバインディングコンバータロールバックすることができます:

public class ImageConverter : IValueConverter 
{ 
    public object Convert(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return new BitmapImage(new Uri(value.ToString())); 
    } 

    public object ConvertBack(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

をし、このようにそれを使用する:アトゥール・グプタによって

<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/> 
+4

(実際にはタイプコンバータは 'BitmapImage'を作成しませんが、' ImageSource'のもう一つのサブクラス: 'BitmapFrameDecode'、内部にあります。) –

+0

@ H.B。画像の変更を維持したい場合は、どのように元に戻しますか? – Igor

+0

コンバーターの代わりに:あなたがバインドしたプロパティ(ここで 'ImageSource')を' Uri'または 'BitmapImage'タイプにしてそこにキャストします。可能な 'null'値(キャスト失敗など)に対処する必要がある場合、あなたのバインディングに' TargetNullValue = {x:Null} 'を追加してください。 – Gerrit

9

URIを画像に変換するIValueConverterインターフェイスの実装が必要です。

BitmapImage image = new BitmapImage(); 
image.BeginInit(); 
image.UriSource = new Uri(value as string); 
image.EndInit(); 

return image; 

は、その後、あなたの結合にコンバータを使用する必要があります:あなたは、単に子供を使用するのではなく、Source属性を設定することができ

<Image> 
    <Image.Source> 
     <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" /> 
    </Image.Source> 
</Image> 
19

IValueConverterのあなたの変換の実装は次のようになります要素。これを行うには、クラスがイメージをビットマップイメージとして返す必要があります。ここで私は

<Image Width="90" Height="90" 
     Source="{Binding Path=ImageSource}" 
     Margin="0,0,0,5" /> 

それをやったし、クラスのプロパティは、単にこの

public object ImageSource { 
    get { 
     BitmapImage image = new BitmapImage(); 

     try { 
      image.BeginInit(); 
      image.CacheOption = BitmapCacheOption.OnLoad; 
      image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; 
      image.UriSource = new Uri(FullPath, UriKind.Absolute); 
      image.EndInit(); 
     } 
     catch{ 
      return DependencyProperty.UnsetValue; 
     } 

     return image; 
    } 
} 

私はそれが値コンバータよりももう少し作業かもしれ仮定が、それはある一つの方法の例です。別のオプション。

+1

はこれと同様の実装が最適です欲しいものを得るために

ImageSourceConverterクラス

を使用することができますビットをバインディングに渡したいとします。ありがとう! –

23

This articleは、いくつかのシナリオをカバーし、サンプルコードを持っています

  1. XAMLのソースプロパティへの通常のリソースイメージのバインド
  2. リソースイメージをバインドするコードの後ろ
  3. アプリケーションでコードのリソースイメージをバインドする。ファイルパスから、それだけに画像データバインディングプロパティ
  4. ファイルパスに結合
  5. を使用して、メモリストリームを介してファイル・パスからGetResourceStream
  6. 読み込み画像(データベースからブログ画像データをロードするときに同じことが適用可能である)
  7. 読み込み画像内部
  8. ポイント5と同じですが、ファイルがハードディスク
6

ここで選択されていることであるた答えに問題があることを上のロックされたのを取得していないことを保証する依存関係プロパティを介して画像制御を持つユーザーコントロール前後にナビゲートすると、コンバータはページが表示されるたびにトリガされます。

これにより、新しいファイルハンドルが継続的に作成され、ファイルがまだ使用されているため、ファイルの削除がブロックされます。これはProcess Explorerを使用して検証できます。画像ファイルは、ある時点で削除される可能性がある場合、このようなコンバータが使用されるかもしれない

using XAML to bind to a System.Drawing.Image into a System.Windows.Image control

欠点このメモリストリーム方式とは、画像(複数可)がロードされることがあり、毎回復号しました "画像が複数回デコードされないようにするには、メモリストリームを使用するのではなく、UriのImage.Sourceプロパティを割り当てます。" ソース: "XAMLを使用してWindowsストアアプリケーションのパフォーマンスのヒント"

パフォーマンスの問題を解決するために、リポジトリパターンを使用してキャッシングレイヤを提供することができます。キャッシングはメモリ内で発生する可能性があり、メモリの問題を引き起こす可能性があります。または、アプリケーションが終了したときに消去できる一時フォルダ内にあるサムネイルファイルとしてキャッシュされる可能性があります。

4

あなたがあなたのビットマップリソースがすでにオブジェクトに読み込まれると

img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png"); 
関連する問題