質問

次のようにカスタム オブジェクトのリストを WPF イメージにバインドしようとしています。

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

しかし、うまくいきません。これが私が得ているエラーです:

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

私には何が欠けているのでしょうか?

役に立ちましたか?

解決

WPF には、特定の型用のコンバータが組み込まれています。画像をバインドすると、 Source プロパティをaに string または Uri 値の場合、WPF は内部で次の値を使用します。 画像ソースコンバータ 値をに変換するには 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}}"/>

他のヒント

この記事 Atul Gupta による、いくつかのシナリオをカバーするサンプル コードがあります。

  1. XAML の Source プロパティにバインドされる通常のリソース画像
  2. リソース イメージをバインディングしますが、コード ビハインドからのものです
  3. Application.GetResourceStream を使用してコードビハインドでリソース イメージをバインドする
  4. メモリ ストリーム経由でファイル パスから画像を読み込みます (データベースからブログの画像データを読み込む場合も同様です)
  5. ファイル パスから画像を読み込みますが、ファイル パス プロパティへのバインドを使用します。
  6. 依存関係プロパティを介して内部的に画像コントロールを持つユーザー コントロールに画像データをバインドする
  7. ポイント 5 と同じですが、ファイルがハードディスク上でロックされないようにします。

子要素を使用せずに、単純に Source 属性を設定することもできます。これを行うには、クラスは画像をビットマップ画像として返す必要があります。これは私が行った方法の一例です

<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;
    }
}

値コンバータよりも少し手間がかかるかもしれませんが、別のオプションです。

の実装が必要です IValueConverter URIを画像に変換するインターフェース。IValueConverter の Convert 実装は次のようになります。

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

return image;

次に、バインディングでコンバータを使用する必要があります。

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

ここで選択した答えの問題は、前後に移動すると、ページが表示されるたびにコンバーターがトリガーされることです。

これにより、新しいファイル ハンドルが継続的に作成され、ファイルはまだ使用されているため、ファイルを削除しようとしてもブロックされます。これは、Process Explorer を使用して確認できます。

画像ファイルがある時点で削除される可能性がある場合は、次のようなコンバータが使用される可能性があります。XAML を使用して System.Drawing.Image を System.Windows.Image コントロールにバインドする

このメモリ ストリーム方式の欠点は、画像が毎回ロードされてデコードされ、キャッシュが行われないことです。"画像が複数回デコードされるのを防ぐには、メモリ ストリームを使用するのではなく、Uri から Image.Source プロパティを割り当てます" 源:「XAML を使用した Windows ストア アプリのパフォーマンスに関するヒント」

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

使ってもいいです

ImageSourceConverter クラス

欲しいものを手に入れるために

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top