3

私のアプリケーションは画面に画像 (ローカル コンピューター上のファイルに基づく画像) を表示し、ユーザーは必要に応じてそれらを削除できます。

ファイルを削除しようとするたびに、次のエラー メッセージが表示されます。

"The process cannot access the file 'C:\\Users\\Dave\\Desktop\\Duplicate\\Swim.JPG' because it is being used by another process."

エラーメッセージを理解しました。

(コンストラクターのパラメーターを介してUserControl)ファイルパスを受け入れ、それを (UserControl) にバインドする がありDataContextます。

この問題のデバッグの一環として、この問題は UserControl 内で DataContext を設定することが原因であることがわかりました。this.DataContext = this;UserControl 内から削除すると、ファイルを削除できます。

だから、私の TestUnit は次のようになります

        Ui.UserControls.ImageControl ic = new ImageControl(
           @"C:\Users\Dave\Desktop\Duplicate\Swim.JPG");

        try
        {
            File.Delete(@"C:\Users\Dave\Desktop\Duplicate\Swim.JPG");
        }
        catch (Exception ex)
        {
            Assert.Fail(ex.Message);
        }

UserControl コードビハインド

    public ImageControl(string path)
    {
        this.FilePath = path;
        this.DataContext = this; // removing this line allows me to delete the file!
        InitializeComponent();
    }

    #region Properties

    private string _filePath;
    public string FilePath
    {
        get { return _filePath; }
        set
        {
            _filePath = value;
            OnPropertyChanged("FilePath");
        }
    }

問題があれば、私の UserControl XAML は「FilePath」にバインドされた「Image」コントロールを使用しています

削除する前に UserControl を null にしようとしましたが、これは役に立ちませんでした。

Dispose()UserControl とメソッド設定内に IDisposible インターフェイスを追加しようとしましたthis.DataContext = null;が、これは役に立ちませんでした。

私は何を間違っていますか?このファイルを削除するにはどうすればよいですか (より正確には、使用しないようにします)。

4

1 に答える 1

5

問題は DataContext ではなく、単純に WPF がファイルから画像をロードする方法にあります。

Sourceイメージ コントロールのプロパティをファイル パスを含む文字列にバインドすると、WPF は基本的に次のようにパスから新しい BitmapFrame オブジェクトを内部的に作成します。

string path = ...
var bitmapImage = BitmapFrame.Create(new Uri(path));

残念ながら、これにより Image ファイルが WPF によって開かれたままになるため、削除することはできません。

これを回避するには、イメージ プロパティのタイプをImageSource(または派生タイプに) 変更し、以下に示すように手動でイメージをロードする必要があります。

public ImageSource ImageSource { get; set; } // omitted OnPropertyChanged for brevity

private ImageSource LoadImage(string path)
{
    var bitmapImage = new BitmapImage();

    using (var stream = new FileStream(path, FileMode.Open))
    {
        bitmapImage.BeginInit();
        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        bitmapImage.StreamSource = stream;
        bitmapImage.EndInit();
        bitmapImage.Freeze(); // optional
    }

    return bitmapImage;
}

...
ImageSource = LoadImage(@"C:\Users\Dave\Desktop\Duplicate\Swim.JPG");
于 2013-10-13T16:26:02.220 に答える