4

次のコードを使用して、wpfアプリに画像を表示しています。

 <Image Source="{Binding Path=TemplateImagePath, Mode=TwoWay}"  Grid.Row="3" Grid.Column="2"  Width="400" Height="200"/>

そして、いくつかのディレクトリをナビゲートすることによって、コンストラクタの背後にあるコード内にそのバインディングプロパティを設定します。以下はコードです。

DirectoryInfo Dir = new DirectoryInfo(@"D:/Template");
            if (Dir.Exists)
            {
                if (Dir.GetFiles().Count() > 0)
                {
                    foreach (FileInfo item in Dir.GetFiles())
                    {
                        TemplateImagePath = item.FullName;
                    }
                }
            }

しかし、ユーザーが他の画像をアップロードする場合は、この古い画像を削除する必要があります。これは、次の方法で実行しており、画像のバインドをnullに設定しています。

DirectoryInfo Dir = new DirectoryInfo(@"D:/Template");
                if (Dir.Exists)
                {
                    if (Dir.GetFiles().Count() > 0)
                    {
                        foreach (FileInfo item in Dir.GetFiles())
                        {
                            TemplateImagePath= null;
                            File.Delete(item.FullName);
                        }
                    }
                }

しかし、他のプロセスで使用されているファイルを削除できないという例外が発生しています。どうすれば削除できますか?

4

2 に答える 2

9

ImageControlに表示されている画像を削除できるようにするには、BitmapCacheOption.OnLoadが設定された新しいBitmapImageまたはBitmapFrameオブジェクトを作成する必要があります。その後、ビットマップはファイルからすぐにロードされ、ファイルはその後ロックされません。

プロパティをからstring TemplateImagePathに変更し、次のImageSource TemplateImageようにバインドします。

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

次のようにプロパティを設定しTemplateImageます。

BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(item.FullName);
image.EndInit();
TemplateImage = image;

またはこれ:

TemplateImage = BitmapFrame.Create(
    new Uri(item.FullName),
    BitmapCreateOptions.None,
    BitmapCacheOption.OnLoad);

TemplateImagePathプロパティへのバインドを維持したい場合は、代わりに、上記のように文字列をImageSourceに変換するバインディングコンバーターを使用できます。

于 2012-10-09T14:35:27.633 に答える
0

Clemensの提案によると、コードを適切に再利用するためのバインディングコンバーターは次のとおりです。

namespace Controls
{
    [ValueConversion(typeof(String), typeof(ImageSource))]
    public class StringToImageSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!(value is string valueString))
            {
                return null;
            }
            try
            {
                ImageSource image = BitmapFrame.Create(new Uri(valueString), BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
                return image;
            }
            catch { return null; }
        }

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

そして、例えば、バインディングのための文字列があります

public string MyImageString { get; set; } = @"C:\test.jpg"

そして、UIではコンバーターが使用されます。私の場合は「Controls」という名前のライブラリからです。

<Window x:Class="MainFrame"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:Controls;assembly=Controls">
    <Window.Resources>
        <controls:StringToImageSourceConverter x:Key="StringToImageSourceConverter" />
    </Window.Resources>
    <Grid>
        <Image Source="{Binding MyImageString, Converter={StaticResource StringToImageSourceConverter}}" />
    </Grid>
</Window>
于 2018-06-19T13:52:35.837 に答える